Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.96k stars 555 forks source link

Found input string with heap-buffer-overflow #19790

Open MoJl4yH opened 2 years ago

MoJl4yH commented 2 years ago

Description

i'm used afl-fuzz for find bug in interpreter perl. And the fuzzer finds a line that results in "heap-buffer-overflow".

For proofs i build perl with this command

CFLAGS+=" -fsanitize=address  -U_FORTIFY_SOURCE  -fno-omit-frame-pointer -fno-common -g" LDFLAGS+=" -fsanitize=address -ldl" ./configure.gnu

And i feed the found string to the input of the perl.

Steps to Reproduce

just pass this segfauit.zip as input.

Expected behavior

=================================================================
==2487953==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60c00000003c at pc 0x5574207f869a bp 0x7ffef058eb30 sp 0x7ffef058eb20
READ of size 4 at 0x60c00000003c thread T0
    #0 0x5574207f8699 in Perl_POPMARK /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/inline.h:285
    #1 0x5574207f8699 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:691
    #2 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #3 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #4 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #5 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #6 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #7 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #8 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #9 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #10 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #11 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #12 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #13 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #14 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #15 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #16 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #17 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #18 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #19 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #20 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #21 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #22 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #23 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #24 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #25 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #26 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #27 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #28 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #29 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #30 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #31 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #32 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #33 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #34 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #35 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #36 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #37 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #38 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #39 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #40 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #41 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #42 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #43 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #44 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #45 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #46 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #47 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #48 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #49 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #50 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #51 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #52 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #53 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #54 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #55 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #56 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #57 0x5574207cc25e in S_sortcv /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:1058
    #58 0x5574207f4cf0 in dynprep /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:184
    #59 0x5574207f4cf0 in S_sortsv_flags_impl /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:354
    #60 0x5574207f4cf0 in Perl_sortsv_flags /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:552
    #61 0x5574207f6f50 in Perl_pp_sort /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/pp_sort.c:901
    #62 0x5574205e942a in Perl_runops_standard /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/run.c:41
    #63 0x5574204206eb in S_run_body /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/perl.c:2716
    #64 0x5574204206eb in perl_run /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/perl.c:2644
    #65 0x5574203a5378 in main /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/perlmain.c:110
    #66 0x7fa8f65cc082 in __libc_start_main ../csu/libc-start.c:308
    #67 0x5574203a5bbd in _start (/home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/perl+0x10dbbd)

0x60c00000003c is located 4 bytes to the left of 128-byte region [0x60c000000040,0x60c0000000c0)
allocated by thread T0 here:
    #0 0x7fa8f6a7ea06 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:153
    #1 0x55742058a1fe in Perl_safesyscalloc /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/util.c:474
    #2 0x55742040c129 in Perl_init_stacks /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/perl.c:4362
    #3 0x55742040c555 in perl_construct /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/perl.c:239
    #4 0x5574203a51ec in main /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/perlmain.c:105
    #5 0x7fa8f65cc082 in __libc_start_main ../csu/libc-start.c:308

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/negoro/SertObject/OpenSourceProject/perl5-5.37.0/inline.h:285 in Perl_POPMARK
Shadow bytes around the buggy address:
  0x0c187fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c187fff8000: fa fa fa fa fa fa fa[fa]00 00 00 00 00 00 00 00
  0x0c187fff8010: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x0c187fff8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff8030: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c187fff8040: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
  0x0c187fff8050: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==2487953==ABORTING

Also, if i will use old version perl (from repo ubuntu), i get "Segmentation fault"

Perl configuration

This is perl 5, version 37, subversion 0 (v5.37.0) built for x86_64-linux

Copyright 1987-2022, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at https://www.perl.org/, the Perl Home Page.

I found about 700 crashes and I'm trying to prove them. i can upload it here, and we try to prove exploitability.

hvds commented 2 years ago

Thanks @MoJl4yH, that is quite a strange one; it reduces to this:

% ./miniperl -we '\sort { 1 } "xx" .. 1'
Useless use of reference constructor in void context at -e line 1.
Argument "xx" isn't numeric in range (or flop) at -e line 1.
miniperl: inline.h:284: Perl_POPMARK: Assertion `(PL_markstack_ptr > PL_markstack) || !"MARK underflow"' failed.
Aborted (core dumped)
% 

The segfault appears to be a bug introduced sometime between 5.24 and 5.28, ameliorated to an underflow panic since 5.34. I'll try to bisect.

MoJl4yH commented 2 years ago

Thanks @MoJl4yH, that is quite a strange one; it reduces to this:

% ./miniperl -we '\sort { 1 } "xx" .. 1'
Useless use of reference constructor in void context at -e line 1.
Argument "xx" isn't numeric in range (or flop) at -e line 1.
miniperl: inline.h:284: Perl_POPMARK: Assertion `(PL_markstack_ptr > PL_markstack) || !"MARK underflow"' failed.
Aborted (core dumped)
% 

The segfault appears to be a bug introduced sometime between 5.24 and 5.28, ameliorated to an underflow panic since 5.34. I'll try to bisect.

Also i found other crash, for example memory leak and about 30 crash with heap-buffer-overflow. I can collect it in archive and send on your e-mail.

hvds commented 2 years ago

The segfault appears to be a bug introduced sometime between 5.24 and 5.28, ameliorated to an underflow panic since 5.34. I'll try to bisect.

I misspoke: the difference between segfault and underflow is the difference between non-debugging and debugging perls.

The crash is introduced by b369834256:

commit b3698342565fb462291fba4b432cfcd05b6eb4e1
Author: Zefram <zefram@fysh.org>
Date:   Fri Jan 27 03:55:46 2017 +0000

    fix range op under aborted constant folding

    When constant-folding a range/flipflop construct, the op_next threading
    of peephole optimisation caused multiple ops in the construct to have
    a null op_next, because the final (and top-level) op in the construct
    is a null op.  This meant that simple restoration of the top-level
    op's op_next after execution wouldn't get it back into a fit state
    to be composed with other ops.  In the event that the range construct
    couldn't be constant-folded this made it compile to a broken optree.
    If it couldn't be constant-folded but could actually be executed, for
    example because it generated a warning, this meant the brokenness would
    be encountered at runtime.  Execution would stop after the range op,
    because of the null op_next.

    To avoid this, temporarily mark the null op as a custom op during the
    peephole optimisation that supports the execution for constant-folding.
    This prevents it being op_next-threaded out, so simple op_next restoring
    then works.  If the constant-folding is aborted, it compiles to an
    operational optree.  However, the suppression of duplicate peephole
    optimisation means that the null op is never ultimately threaded out
    as it should be.  For the time being, this stands as a cost of failed
    constant-folding of range constructs.

    Fixes [perl #130639].

(That was #15832.)

@iabyn that last paragraph is curious, could this also trip over the changes you made to the handling of null ops?

I hope someone more familiar with optrees than I can analyse this further.

hvds commented 2 years ago

Also i found other crash, for example memory leak and about 30 crash with heap-buffer-overflow. I can collect it in archive and send on your e-mail.

Sure if you like, you'll find my email in AUTHORS if you need it.

Please consider minimizing the test cases first. Either afl-cmin or afl-tmin will try to do that for you (I forget the difference between them), but you'll need to verify that the reduced versions still fail in the same way.

Hugo van der Sanden

mauke commented 1 year ago
$ ./perl -Ds -we '\sort { 1 } "xx" .. 1'
    =>  *  
    =>  *  
    =>  *  PV("xx"\0)  
    =>  *  PV("xx"\0)  
    =>  *  PV("xx"\0)  IV(1)  
Useless use of reference constructor in void context at -e line 1.

EXECUTING...

    =>  
    =>  
    =>  
    =>  *  
    =>  **  
    =>  **  
    =>  **  PVNV("xx"\0)  
    =>  **  PVNV("xx"\0)  
    =>  **  PVNV("xx"\0)  IV(1)  
Argument "xx" isn't numeric in range (or flop) at -e line 1.
    =>  **  IV(0)  IV(1)  
    =>  **  IV(0)  IV(1)  
    =>  
    =>  
    =>  PVNV("xx"\0)  
    =>  PVNV("xx"\0)  
    =>  PVNV("xx"\0)  IV(1)  
    =>  IV(0)  IV(1)  
    =>  IV(0)  IV(1)  
    =>  
    =>  
    =>  PVNV("xx"\0)  
    =>  PVNV("xx"\0)  
    =>  PVNV("xx"\0)  IV(1)  
    =>  IV(0)  IV(1)  
    =>  IV(0)  IV(1)  
perl: inline.h:379: Perl_POPMARK: Assertion `(PL_markstack_ptr > PL_markstack) || !"MARK underflow"' failed.
Aborted

This looks like a loop to me. Somehow "xx" and 1 are getting pushed on the stack (and turned into 0 1) repeatedly.