Perl / perl5

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

heap-use-after-free in Perl_op_free #16886

Open p5pRT opened 5 years ago

p5pRT commented 5 years ago

Migrated from rt.perl.org#133925 (status was 'open')

Searchable as RT133925$

p5pRT commented 5 years ago

From @dur-randir

Created by @dur-randir

While fuzzing perl v5.29.8-21-gde59f38ed9 built with afl and run under libdislocator\, I found the following program

s\,(?{0=qr{(?{{}])}};{}})\,\,

to perform an access outside of an allocated memory slot. ASAN diagnostics are​:

==22697==ERROR​: AddressSanitizer​: heap-use-after-free on address 0x619000001c68 at pc 0x00000050f74d bp 0x7ffe9e708ec0 sp 0x7ffe9e708eb8 READ of size 2 at 0x619000001c68 thread T0   #0 0x50f74c in Perl_op_free /home/afl/afl-asan/op.c​:888​:27   #1 0x710f5e in Perl_yyparse /home/afl/afl-asan/perly.c​:499​:25   #2 0x5ebb7a in S_parse_body /home/afl/afl-asan/perl.c​:2507​:9   #3 0x5e1f33 in perl_parse /home/afl/afl-asan/perl.c​:1798​:2   #4 0x50b5fe in main /home/afl/afl-asan/perlmain.c​:126​:10   #5 0x7f1c15ef709a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)   #6 0x43bde9 in _start (/home/afl/afl-asan/perl+0x43bde9)

0x619000001c68 is located 744 bytes inside of 1024-byte region [0x619000001980\,0x619000001d80) freed by thread T0 here​:   #0 0x4da220 in __interceptor_cfree.localalias.0 (/home/afl/afl-asan/perl+0x4da220)   #1 0x50dbe1 in Perl_opslab_free /home/afl/afl-asan/op.c​:535​:2   #2 0x50e832 in Perl_opslab_force_free /home/afl/afl-asan/op.c​:582​:5   #3 0x715d32 in Perl_cv_undef_flags /home/afl/afl-asan/pad.c​:341​:17   #4 0xa1f14a in Perl_sv_clear /home/afl/afl-asan/sv.c​:6631​:6   #5 0xa27897 in Perl_sv_free2 /home/afl/afl-asan/sv.c​:7092​:9   #6 0x70e48d in S_SvREFCNT_dec /home/afl/afl-asan/./inline.h​:216​:6   #7 0x70e48d in Perl_yyparse /home/afl/afl-asan/perly.c​:439   #8 0x5ebb7a in S_parse_body /home/afl/afl-asan/perl.c​:2507​:9   #9 0x5e1f33 in perl_parse /home/afl/afl-asan/perl.c​:1798​:2   #10 0x50b5fe in main /home/afl/afl-asan/perlmain.c​:126​:10   #11 0x7f1c15ef709a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)

previously allocated by thread T0 here​:   #0 0x4da590 in calloc (/home/afl/afl-asan/perl+0x4da590)   #1 0x50c770 in S_new_slab /home/afl/afl-asan/op.c​:266​:30   #2 0x50c770 in Perl_Slab_Alloc /home/afl/afl-asan/op.c​:372   #3 0x539488 in Perl_newUNOP /home/afl/afl-asan/op.c​:6215​:5   #4 0x70d6d9 in Perl_yyparse /home/afl/afl-asan/perly.y​:1086​:23   #5 0x5ebb7a in S_parse_body /home/afl/afl-asan/perl.c​:2507​:9   #6 0x5e1f33 in perl_parse /home/afl/afl-asan/perl.c​:1798​:2   #7 0x50b5fe in main /home/afl/afl-asan/perlmain.c​:126​:10   #8 0x7f1c15ef709a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)

This is a regression between 5.20 and 5.22\, bisect points to

commit 9b6b7be8acad62650aa5c229e89fad6706c8a0b0 Author​: Father Chrysostomos \sprout@​cpan\.org Date​: Thu Jan 8 18​:49​:32 2015 -0800

  Simplify s/// and tr/// parsing logic

  These two operators were being translated into subst(""\,"") and   tr(""\,"") by the lexer. Then pmruntime in op.c would take apart the   resulting list op. Instead of constructing a list op only to take it   apart again\, feed the replacement part to pmruntime separately. We   can achieve this by introducing a new token ('/') that the parser rec-   ognizes as introducing a replacement.

  If we had followed this approach to begin with\, then bug #123542 would   never have happened.

Perl Info ``` Flags: category=core severity=medium Site configuration information for perl 5.29.9: Configured by dur-randir at Wed Feb 27 14:51:01 MSK 2019. Summary of my perl5 (revision 5 version 29 subversion 9) configuration: Commit id: c1e47bad34ce1d9c84ed57c9b8978bcbd5a02e98 Platform: osname=darwin osvers=13.4.0 archname=darwin-thread-multi-2level uname='darwin isengard.local 13.4.0 darwin kernel version 13.4.0: mon jan 11 18:17:34 pst 2016; root:xnu-2422.115.15~1release_x86_64 x86_64 ' config_args='-de -Dusedevel -DDEBUGGING -Dusethreads' hint=recommended useposix=true d_sigaction=define useithreads=define usemultiplicity=define use64bitint=define use64bitall=define uselongdouble=undef usemymalloc=n default_inc_excludes_dot=define bincompat5005=undef Compiler: cc='cc' ccflags ='-fno-common -DPERL_DARWIN -mmacosx-version-min=10.9 -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -DPERL_USE_SAFE_PUTENV' optimize='-O3 -g' cppflags='-fno-common -DPERL_DARWIN -mmacosx-version-min=10.9 -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='' gccversion='4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)' gccosandvers='' intsize=4 longsize=8 ptrsize=8 doublesize=8 byteorder=12345678 doublekind=3 d_longlong=define longlongsize=8 d_longdbl=define longdblsize=16 longdblkind=3 ivtype='long' ivsize=8 nvtype='double' nvsize=8 Off_t='off_t' lseeksize=8 alignbytes=8 prototype=define Linker and Libraries: ld='cc' ldflags =' -mmacosx-version-min=10.9 -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/lib /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib /usr/lib libs=-lpthread -lgdbm -ldbm -ldl -lm -lutil -lc perllibs=-lpthread -ldl -lm -lutil -lc libc= so=dylib useshrplib=false libperl=libperl.a gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs dlext=bundle d_dlsymun=undef ccdlflags=' ' cccdlflags=' ' lddlflags=' -mmacosx-version-min=10.9 -bundle -undefined dynamic_lookup -L/usr/local/lib -fstack-protector' @INC for perl 5.29.9: lib /usr/local/lib/perl5/site_perl/5.29.9/darwin-thread-multi-2level /usr/local/lib/perl5/site_perl/5.29.9 /usr/local/lib/perl5/5.29.9/darwin-thread-multi-2level /usr/local/lib/perl5/5.29.9 Environment for perl 5.29.9: DYLD_LIBRARY_PATH (unset) HOME=/Users/dur-randir LANG=en_US.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/Users/dur-randir/perlbrew/bin:/Users/dur-randir/perlbrew/perls/perl-5.22.1/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/texbin PERLBREW_HOME=/Users/dur-randir/.perlbrew PERLBREW_MANPATH=/Users/dur-randir/perlbrew/perls/perl-5.22.1/man PERLBREW_PATH=/Users/dur-randir/perlbrew/bin:/Users/dur-randir/perlbrew/perls/perl-5.22.1/bin PERLBREW_PERL=perl-5.22.1 PERLBREW_ROOT=/Users/dur-randir/perlbrew PERLBREW_SHELLRC_VERSION=0.84 PERLBREW_VERSION=0.84 PERL_BADLANG (unset) SHELL=/usr/local/bin/zsh ```
p5pRT commented 5 years ago

From @tonycoz

On Tue\, 12 Mar 2019 09​:44​:20 -0700\, randir wrote​:

While fuzzing perl v5.29.8-21-gde59f38ed9 built with afl and run under libdislocator\, I found the following program

s\,(?{0=qr{(?{{}])}};{}})\,\,

to perform an access outside of an allocated memory slot. ASAN diagnostics are​:

==22697==ERROR​: AddressSanitizer​: heap-use-after-free on address 0x619000001c68 at pc 0x00000050f74d bp 0x7ffe9e708ec0 sp 0x7ffe9e708eb8 READ of size 2 at 0x619000001c68 thread T0 #0 0x50f74c in Perl_op_free /home/afl/afl-asan/op.c​:888​:27 #1 0x710f5e in Perl_yyparse /home/afl/afl-asan/perly.c​:499​:25 #2 0x5ebb7a in S_parse_body /home/afl/afl-asan/perl.c​:2507​:9 #3 0x5e1f33 in perl_parse /home/afl/afl-asan/perl.c​:1798​:2 #4 0x50b5fe in main /home/afl/afl-asan/perlmain.c​:126​:10 #5 0x7f1c15ef709a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a) #6 0x43bde9 in _start (/home/afl/afl-asan/perl+0x43bde9)

0x619000001c68 is located 744 bytes inside of 1024-byte region [0x619000001980\,0x619000001d80) freed by thread T0 here​: #0 0x4da220 in __interceptor_cfree.localalias.0 (/home/afl/afl-asan/perl+0x4da220) #1 0x50dbe1 in Perl_opslab_free /home/afl/afl-asan/op.c​:535​:2 #2 0x50e832 in Perl_opslab_force_free /home/afl/afl- asan/op.c​:582​:5 #3 0x715d32 in Perl_cv_undef_flags /home/afl/afl-asan/pad.c​:341​:17 #4 0xa1f14a in Perl_sv_clear /home/afl/afl-asan/sv.c​:6631​:6 #5 0xa27897 in Perl_sv_free2 /home/afl/afl-asan/sv.c​:7092​:9 #6 0x70e48d in S_SvREFCNT_dec /home/afl/afl-asan/./inline.h​:216​:6 #7 0x70e48d in Perl_yyparse /home/afl/afl-asan/perly.c​:439 #8 0x5ebb7a in S_parse_body /home/afl/afl-asan/perl.c​:2507​:9 #9 0x5e1f33 in perl_parse /home/afl/afl-asan/perl.c​:1798​:2 #10 0x50b5fe in main /home/afl/afl-asan/perlmain.c​:126​:10 #11 0x7f1c15ef709a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)

previously allocated by thread T0 here​: #0 0x4da590 in calloc (/home/afl/afl-asan/perl+0x4da590) #1 0x50c770 in S_new_slab /home/afl/afl-asan/op.c​:266​:30 #2 0x50c770 in Perl_Slab_Alloc /home/afl/afl-asan/op.c​:372 #3 0x539488 in Perl_newUNOP /home/afl/afl-asan/op.c​:6215​:5 #4 0x70d6d9 in Perl_yyparse /home/afl/afl-asan/perly.y​:1086​:23 #5 0x5ebb7a in S_parse_body /home/afl/afl-asan/perl.c​:2507​:9 #6 0x5e1f33 in perl_parse /home/afl/afl-asan/perl.c​:1798​:2 #7 0x50b5fe in main /home/afl/afl-asan/perlmain.c​:126​:10 #8 0x7f1c15ef709a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)

This is a regression between 5.20 and 5.22\, bisect points to

commit 9b6b7be8acad62650aa5c229e89fad6706c8a0b0 Author​: Father Chrysostomos \sprout@​cpan\.org Date​: Thu Jan 8 18​:49​:32 2015 -0800

Simplify s/// and tr/// parsing logic

These two operators were being translated into subst(""\,"") and tr(""\,"") by the lexer. Then pmruntime in op.c would take apart the resulting list op. Instead of constructing a list op only to take it apart again\, feed the replacement part to pmruntime separately. We can achieve this by introducing a new token ('/') that the parser rec- ognizes as introducing a replacement.

If we had followed this approach to begin with\, then bug #123542 would never have happened.

This happens while parsing code fed to the interpreter\, so isn't a security issue under our usual criteria.

Tony

p5pRT commented 5 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 5 years ago

From @iabyn

On Tue\, Apr 16\, 2019 at 09​:59​:40PM -0700\, Tony Cook via RT wrote​:

On Tue\, 12 Mar 2019 09​:44​:20 -0700\, randir wrote​:

While fuzzing perl v5.29.8-21-gde59f38ed9 built with afl and run under libdislocator\, I found the following program

s\,(?{0=qr{(?{{}])}};{}})\,\,

to perform an access outside of an allocated memory slot. ASAN diagnostics are​:

This happens while parsing code fed to the interpreter\, so isn't a security issue under our usual criteria.

I've now moved this ticket to the public queue

-- The Enterprise is captured by a vastly superior alien intelligence which does not put them on trial.   -- Things That Never Happen in "Star Trek" #10