Closed p5pRT closed 8 years ago
Greetings Porters\,
I have compiled bleadperl with the afl-gcc compiler using:
./Configure -Dusedevel -Dprefix='/usr/local/perl-afl' -Dcc=afl-gcc -Duselongdouble -Duse64bitint -Doptimize=-g -Uversiononly -Uman1dir -Uman3dir -Dusethreads -des AFL_HARDEN=1 make && make test
And then fuzzed the resulting binary using:
AFL_NO_VAR_CHECK=1 afl-fuzz -i in -o out bin/perl @@
After reducing testcases using `afl-tmin` and filtering out testcases that are merely iterations of "#!perl -u"\, I have located the following testcase that triggers a panic in the perl interpreter. The testcase is the 62-byte binary file: (octal bytes)
root@nagios:/usr/local/perl-afl/out# od -c allcrash/f2i000000 0000000 / \ N { } 0 0 0 0 0 0 0 0 337 337 337 0000020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000060 0 0 0 0 0 0 0 0 0 0 375 / i \n 0000076
When executed\, the following bad things happen:
panic: reg_node overrun trying to emit 0\, 8833280>=8833280 at test line 1.
The program exits cleanly\, apart from the panic\, so there is no backtrace for GDB to produce\, and Valgrind finds no errors. The next bug I am about to submit is an even more esoteric version of this case which fails somewhat more spectacularly.
**PERL -V**
Summary of my perl5 (revision 5 version 23 subversion 3) configuration: Commit id: 9ae0115f0b854d654461d3c5bbcaa938516d0f4e Platform: osname=linux\, osvers=2.6.32-5-686\, archname=i686-linux-64int-ld-thread-multi uname='linux nagios 2.6.32-5-686 #1 smp tue may 13 16:33:32 utc 2014 i686 gnulinux ' config_args='-Dusedevel -Dprefix=/usr/local/perl-afl -Dcc=afl-gcc -Duselongdouble -Duse64bitint -Doptimize=-g -Uversiononly -Uman1dir -Uman3dir -des' hint=previous\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define use64bitint=define\, use64bitall=undef\, uselongdouble=define usemymalloc=n\, bincompat5005=undef Compiler: cc='afl-gcc'\, ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-g'\, cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' ccversion=''\, gccversion='4.4.5'\, gccosandvers='' intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=12345678\, doublekind=3 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12\, longdblkind=3 ivtype='long long'\, ivsize=8\, nvtype='long double'\, nvsize=12\, Off_t='off_t'\, lseeksize=8 alignbytes=4\, prototype=define Linker and Libraries: ld='afl-gcc'\, ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /usr/lib/gcc/i486-linux-gnu/4.4.5/include-fixed /usr/lib /lib/../lib /usr/lib/../lib /lib /usr/lib/i486-linux-gnu /usr/lib64 /usr/local/lib /usr/lib/gcc/i486-linux-gnu/4.4.5/include-fixed /usr/lib /usr/local/lib /usr/lib/gcc/i486-linux-gnu/4.4.5/include-fixed /usr/lib /usr/local/lib /usr/lib/gcc/i486-linux-gnu/4.4.5/include-fixed /usr/lib libs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc libc=libc-2.11.3.so\, so=so\, useshrplib=false\, libperl=libperl.a gnulibc_version='2.11.3' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E' cccdlflags='-fPIC'\, lddlflags='-shared -g -L/usr/local/lib -fstack-protector'
Characteristics of this binary (from libperl): Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS PERL_COPY_ON_WRITE PERL_DONT_CREATE_GVSV PERL_HASH_FUNC_ONE_AT_A_TIME_HARD PERL_IMPLICIT_CONTEXT PERL_PRESERVE_IVUV PERL_USE_DEVEL USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_LOCALE_TIME USE_LONG_DOUBLE USE_PERLIO USE_PERL_ATOF USE_REENTRANT_API Built under linux Compiled at Sep 2 2015 09:16:23 @INC: /usr/local/perl-afl/lib/site_perl/5.23.3/i686-linux-64int-ld /usr/local/perl-afl/lib/site_perl/5.23.3 /usr/local/perl-afl/lib/5.23.3/i686-linux-64int-ld /usr/local/perl-afl/lib/5.23.3 /usr/local/perl-afl/lib/site_perl/5.23.2 /usr/local/perl-afl/lib/site_perl .
Greetings Porters\,
I have compiled bleadperl with the afl-gcc compiler using:
./Configure -Dusedevel -Dprefix='/usr/local/perl-afl' -Dcc=afl-gcc -Duselongdouble -Duse64bitint -Doptimize=-g -Uversiononly -Uman1dir -Uman3dir -Dusethreads -des AFL_HARDEN=1 make && make test
And then fuzzed the resulting binary using:
AFL_NO_VAR_CHECK=1 afl-fuzz -i in -o out bin/perl @@
After reducing testcases using `afl-tmin` and filtering out testcases that are merely iterations of "#!perl -u"\, I have located the following testcase that triggers a panic in the perl interpreter. The testcase is the 74-byte binary file: (octal bytes)
root@nagios:/usr/local/perl-afl/out# od -c allcrash/f2i000000 0000000 / 0 0 0 0 0 0 0 0 0 \ N { } 0 0 0000020 0 0 0 0 0 337 337 0 337 337 337 337 337 0 0 0 0000040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000060 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000100 0 0 0 0 0 0 0 375 / i 0000112
Attached as "f2i000000".
I'm reasonably certain that this is a duplicate of another bug\, because I've seen the below sort of backtrace in a different bug\, that also related to a "creative" regular expression. However\, I can't find that bug. I'm also not sure if this is an upstream\, because Perl is trying to croak here\, and does so successfully under very similar circumstances.
When executed\, the following bad things happen:
root@nagios:/usr/local/perl-afl/out# ../bin/perl allcrash/f2i000000 *** glibc detected *** ../bin/perl: free(): invalid next size (normal): 0x0a3a2260 *** ======= Backtrace: ========= /lib/i686/cmov/libc.so.6(+0x6af71)[0xb7619f71] /lib/i686/cmov/libc.so.6(+0x6c7c8)[0xb761b7c8] /lib/i686/cmov/libc.so.6(+0x703ba)[0xb761f3ba] /lib/i686/cmov/libc.so.6(realloc+0xdd)[0xb761f97d] ../bin/perl(Perl_safesysrealloc+0xc8)[0x82d4ff8] ../bin/perl(Perl_sv_grow+0x4c4)[0x83dc5b4] ../bin/perl(Perl_sv_catpvn_flags+0x306)[0x83fbd76] ../bin/perl(Perl_sv_vcatpvfn_flags+0x4fea)[0x83ba5ea] ../bin/perl(Perl_sv_vsetpvfn+0xcb)[0x84047fb] ../bin/perl(Perl_vmess+0x13f)[0x82e35af] ../bin/perl(Perl_vcroak+0x98)[0x82ddf58] ../bin/perl(Perl_parse_unicode_opts+0x0)[0x82de1f0] ../bin/perl[0x82076df] ../bin/perl[0x826295c] ../bin/perl(Perl_re_op_compile+0x306a)[0x829873a] ../bin/perl(Perl_pmruntime+0x1380)[0x80d7580] ../bin/perl(Perl_yyparse+0x4593)[0x81d88b3] ../bin/perl[0x811467f] ../bin/perl(perl_parse+0x189f)[0x8117b1f] ../bin/perl(main+0x119)[0x80629d9] /lib/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb75c5ca6] ../bin/perl[0x8062821] ======= Memory map: ======== 08048000-0875c000 r-xp 00000000 08:01 734611 /usr/local/perl-afl/bin/perl 0875c000-0875e000 rw-p 00713000 08:01 734611 /usr/local/perl-afl/bin/perl 0a387000-0a3a8000 rw-p 00000000 00:00 0 [heap] b7300000-b7321000 rw-p 00000000 00:00 0 b7321000-b7400000 ---p 00000000 00:00 0 b741a000-b7437000 r-xp 00000000 08:01 432483 /lib/libgcc_s.so.1 b7437000-b7438000 rw-p 0001c000 08:01 432483 /lib/libgcc_s.so.1 b7438000-b75ad000 r--p 00000000 08:01 99452 /usr/lib/locale/locale-archive b75ad000-b75af000 rw-p 00000000 00:00 0 b75af000-b76ef000 r-xp 00000000 08:01 449158 /lib/i686/cmov/libc-2.11.3.so b76ef000-b76f0000 ---p 00140000 08:01 449158 /lib/i686/cmov/libc-2.11.3.so b76f0000-b76f2000 r--p 00140000 08:01 449158 /lib/i686/cmov/libc-2.11.3.so b76f2000-b76f3000 rw-p 00142000 08:01 449158 /lib/i686/cmov/libc-2.11.3.so b76f3000-b76f6000 rw-p 00000000 00:00 0 b76f6000-b76f8000 r-xp 00000000 08:01 449149 /lib/i686/cmov/libutil-2.11.3.so b76f8000-b76f9000 r--p 00001000 08:01 449149 /lib/i686/cmov/libutil-2.11.3.so b76f9000-b76fa000 rw-p 00002000 08:01 449149 /lib/i686/cmov/libutil-2.11.3.so b76fa000-b7703000 r-xp 00000000 08:01 449143 /lib/i686/cmov/libcrypt-2.11.3.so b7703000-b7704000 r--p 00008000 08:01 449143 /lib/i686/cmov/libcrypt-2.11.3.so b7704000-b7705000 rw-p 00009000 08:01 449143 /lib/i686/cmov/libcrypt-2.11.3.so b7705000-b772c000 rw-p 00000000 00:00 0 b772c000-b7750000 r-xp 00000000 08:01 449140 /lib/i686/cmov/libm-2.11.3.so b7750000-b7751000 r--p 00023000 08:01 449140 /lib/i686/cmov/libm-2.11.3.so b7751000-b7752000 rw-p 00024000 08:01 449140 /lib/i686/cmov/libm-2.11.3.so b7752000-b7754000 r-xp 00000000 08:01 449139 /lib/i686/cmov/libdl-2.11.3.so b7754000-b7755000 r--p 00001000 08:01 449139 /lib/i686/cmov/libdl-2.11.3.so b7755000-b7756000 rw-p 00002000 08:01 449139 /lib/i686/cmov/libdl-2.11.3.so b7756000-b7757000 rw-p 00000000 00:00 0 b7757000-b776a000 r-xp 00000000 08:01 449142 /lib/i686/cmov/libnsl-2.11.3.so b776a000-b776b000 r--p 00012000 08:01 449142 /lib/i686/cmov/libnsl-2.11.3.so b776b000-b776c000 rw-p 00013000 08:01 449142 /lib/i686/cmov/libnsl-2.11.3.so b776c000-b776e000 rw-p 00000000 00:00 0 b776e000-b7783000 r-xp 00000000 08:01 449148 /lib/i686/cmov/libpthread-2.11.3.so b7783000-b7784000 r--p 00014000 08:01 449148 /lib/i686/cmov/libpthread-2.11.3.so b7784000-b7785000 rw-p 00015000 08:01 449148 /lib/i686/cmov/libpthread-2.11.3.so b7785000-b7787000 rw-p 00000000 00:00 0 b7797000-b7799000 rw-p 00000000 00:00 0 b7799000-b779a000 r-xp 00000000 00:00 0 [vdso] b779a000-b77b5000 r-xp 00000000 08:01 432496 /lib/ld-2.11.3.so b77b5000-b77b6000 r--p 0001b000 08:01 432496 /lib/ld-2.11.3.so b77b6000-b77b7000 rw-p 0001c000 08:01 432496 /lib/ld-2.11.3.so bf8b7000-bf8cc000 rw-p 00000000 00:00 0 [stack] Aborted
When Perl is instead configured with PERL_MALLOC_WRAP and DEBUGGING\, or when the testcase is shortened by removing even one zero\, an error such as the following appears\, which I've reported as a separate bug\, [perl #125990]
panic: reg_node overrun trying to emit 0\, a18b1fc>=a18b1f8 at test line 1.
**GDB**
(the above output\, followed by...)
Program received signal SIGABRT\, Aborted.
0xb7fe2424 in __kernel_vsyscall ()
(gdb) bt
#0 0xb7fe2424 in __kernel_vsyscall ()
#1 0xb7e22781 in *__GI_raise (sig=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2 0xb7e25bb2 in *__GI_abort () at abort.c:92
#3 0xb7e58e75 in __libc_message (do_abort=2\,
fmt=0xb7f1dbd8 "*** glibc detected *** %s: %s: 0x%s ***\n")
at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#4 0xb7e62f71 in malloc_printerr (action=\
**VALGRIND**
Valgrind seems to cause different behavior in this testcase\, allowing Perl to panic rather than throw the glibc error above. Not sure how to get around that.
==9005== Memcheck\, a memory error detector ==9005== Copyright (C) 2002-2010\, and GNU GPL'd\, by Julian Seward et al. ==9005== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info ==9005== Command: ../bin/perl allcrash/f2i000000 ==9005== ==9005== Invalid write of size 1 ==9005== at 0x8289A46: S_regpiece (regcomp.c:12725) ==9005== by 0x8294A7E: S_regbranch (regcomp.c:10754) ==9005== by 0x825DFB0: S_reg (regcomp.c:10504) ==9005== by 0x8298739: Perl_re_op_compile (regcomp.c:6902) ==9005== by 0x80D757F: Perl_pmruntime (op.c:5579) ==9005== by 0x81D88B2: Perl_yyparse (perly.y:1038) ==9005== by 0x811467E: S_parse_body (perl.c:2296) ==9005== by 0x8117B1E: perl_parse (perl.c:1626) ==9005== by 0x80629D8: main (perlmain.c:114) ==9005== Address 0x4237164 is 0 bytes after a block of size 116 alloc'd ==9005== at 0x4023F50: malloc (vg_replace_malloc.c:236) ==9005== by 0x82D4537: Perl_safesysmalloc (util.c:149) ==9005== by 0x8297CC1: Perl_re_op_compile (regcomp.c:6752) ==9005== by 0x80D757F: Perl_pmruntime (op.c:5579) ==9005== by 0x81D88B2: Perl_yyparse (perly.y:1038) ==9005== by 0x811467E: S_parse_body (perl.c:2296) ==9005== by 0x8117B1E: perl_parse (perl.c:1626) ==9005== by 0x80629D8: main (perlmain.c:114) ==9005== panic: reg_node overrun trying to emit 0\, 4237168>=4237164 at allcrash/f2i000000 line 1. ==9005== ==9005== HEAP SUMMARY: ==9005== in use at exit: 89\,869 bytes in 582 blocks ==9005== total heap usage: 757 allocs\, 175 frees\, 122\,964 bytes allocated ==9005== ==9005== LEAK SUMMARY: ==9005== definitely lost: 6\,243 bytes in 15 blocks ==9005== indirectly lost: 83\,626 bytes in 567 blocks ==9005== possibly lost: 0 bytes in 0 blocks ==9005== still reachable: 0 bytes in 0 blocks ==9005== suppressed: 0 bytes in 0 blocks ==9005== Rerun with --leak-check=full to see details of leaked memory ==9005== ==9005== For counts of detected and suppressed errors\, rerun with: -v ==9005== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 25 from 8)
**BISECT**
First commit that crashes in this particular way is: commit 75697d6e4ef98ece405210de48e7529d01b619bf Author: Karl Williamson \khw@​cpan\.org Date: Sun Dec 21 22:02:30 2014 -0700
Empty \N{} in regex pattern should force /d to /u
\N{} is for Unicode names\, even if the name is actually omitted.
(Accepting an empty name is\, I believe\, an accident\, and now is
supported only for backwards compatibility.)
**PERL -V**
Summary of my perl5 (revision 5 version 23 subversion 3) configuration: Commit id: 9ae0115f0b854d654461d3c5bbcaa938516d0f4e Platform: osname=linux\, osvers=2.6.32-5-686\, archname=i686-linux-64int-ld-thread-multi uname='linux nagios 2.6.32-5-686 #1 smp tue may 13 16:33:32 utc 2014 i686 gnulinux ' config_args='-Dusedevel -Dprefix=/usr/local/perl-afl -Dcc=afl-gcc -Duselongdouble -Duse64bitint -Doptimize=-g -Uversiononly -Uman1dir -Uman3dir -des' hint=previous\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define use64bitint=define\, use64bitall=undef\, uselongdouble=define usemymalloc=n\, bincompat5005=undef Compiler: cc='afl-gcc'\, ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-g'\, cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' ccversion=''\, gccversion='4.4.5'\, gccosandvers='' intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=12345678\, doublekind=3 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12\, longdblkind=3 ivtype='long long'\, ivsize=8\, nvtype='long double'\, nvsize=12\, Off_t='off_t'\, lseeksize=8 alignbytes=4\, prototype=define Linker and Libraries: ld='afl-gcc'\, ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /usr/lib/gcc/i486-linux-gnu/4.4.5/include-fixed /usr/lib /lib/../lib /usr/lib/../lib /lib /usr/lib/i486-linux-gnu /usr/lib64 /usr/local/lib /usr/lib/gcc/i486-linux-gnu/4.4.5/include-fixed /usr/lib /usr/local/lib /usr/lib/gcc/i486-linux-gnu/4.4.5/include-fixed /usr/lib /usr/local/lib /usr/lib/gcc/i486-linux-gnu/4.4.5/include-fixed /usr/lib libs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc libc=libc-2.11.3.so\, so=so\, useshrplib=false\, libperl=libperl.a gnulibc_version='2.11.3' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E' cccdlflags='-fPIC'\, lddlflags='-shared -g -L/usr/local/lib -fstack-protector'
Characteristics of this binary (from libperl): Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS PERL_COPY_ON_WRITE PERL_DONT_CREATE_GVSV PERL_HASH_FUNC_ONE_AT_A_TIME_HARD PERL_IMPLICIT_CONTEXT PERL_PRESERVE_IVUV PERL_USE_DEVEL USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_LOCALE_TIME USE_LONG_DOUBLE USE_PERLIO USE_PERL_ATOF USE_REENTRANT_API Built under linux Compiled at Sep 2 2015 09:16:23 @INC: /usr/local/perl-afl/lib/site_perl/5.23.3/i686-linux-64int-ld /usr/local/perl-afl/lib/site_perl/5.23.3 /usr/local/perl-afl/lib/5.23.3/i686-linux-64int-ld /usr/local/perl-afl/lib/5.23.3 /usr/local/perl-afl/lib/site_perl/5.23.2 /usr/local/perl-afl/lib/site_perl .
On Fri Sep 04 17:27:40 2015\, dcollinsn@gmail.com wrote:
root@nagios:/usr/local/perl-afl/out# od -c allcrash/f2i000000 0000000 / \ N { } 0 0 0 0 0 0 0 0 337 337 337 0000020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000060 0 0 0 0 0 0 0 0 0 0 375 / i \n 0000076
Could you attach this file please?
Thanks\, Tony
The RT System itself - Status changed from 'new' to 'open'
On Sun Sep 06 21:20:19 2015\, tonyc wrote:
On Fri Sep 04 17:27:40 2015\, dcollinsn@gmail.com wrote:
root@nagios:/usr/local/perl-afl/out# od -c allcrash/f2i000000 0000000 / \ N { } 0 0 0 0 0 0 0 0 337 337 337 0000020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000060 0 0 0 0 0 0 0 0 0 0 375 / i \n 0000076
Could you attach this file please?
I ended up generating it\, attached as 125990.pl.
The problem is len at line 12988 is different between pass 1 and pass 2\, with values of 54 and 57.
This leads to a simplified reproducer:
tony@mars:.../git/perl$ od -c ../125990b.pl 0000000 / \ N { } 337 337 337 375 / i \n 0000014
attached as 125990b.pl\, which should be simpler to debug to find where the mismatch occurs (which I'll do tomorrow if someone else doesn't beat me to it.)
Tony
On Mon Sep 07 23:57:17 2015\, tonyc wrote:
On Sun Sep 06 21:20:19 2015\, tonyc wrote:
On Fri Sep 04 17:27:40 2015\, dcollinsn@gmail.com wrote:
root@nagios:/usr/local/perl-afl/out# od -c allcrash/f2i000000 0000000 / \ N { } 0 0 0 0 0 0 0 0 337 337 337 0000020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000060 0 0 0 0 0 0 0 0 0 0 375 / i \n 0000076
Could you attach this file please?
I ended up generating it\, attached as 125990.pl.
RT seems to have attached the same content for both files. Trying 125990.pl again.
Tony
This is likely from my code\, so I'm taking the ticket to look at it.
On 09/08/2015 12:58 AM\, Tony Cook via RT wrote:
On Mon Sep 07 23:57:17 2015\, tonyc wrote:
On Sun Sep 06 21:20:19 2015\, tonyc wrote:
On Fri Sep 04 17:27:40 2015\, dcollinsn@gmail.com wrote:
root@nagios:/usr/local/perl-afl/out# od -c allcrash/f2i000000 0000000 / \ N { } 0 0 0 0 0 0 0 0 337 337 337 0000020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000060 0 0 0 0 0 0 0 0 0 0 375 / i \n 0000076
Could you attach this file please?
I ended up generating it\, attached as 125990.pl.
RT seems to have attached the same content for both files. Trying 125990.pl again.
Tony
--- via perlbug: queue: perl5 status: open https://rt-archive.perl.org/perl5/Ticket/Display.html?id=125990
On Fri Sep 04 17:28:18 2015\, dcollinsn@gmail.com wrote:
Greetings Porters\,
I have compiled bleadperl with the afl-gcc compiler using:
./Configure -Dusedevel -Dprefix='/usr/local/perl-afl' -Dcc=afl-gcc -Duselongdouble -Duse64bitint -Doptimize=-g -Uversiononly -Uman1dir -Uman3dir -Dusethreads -des AFL_HARDEN=1 make && make test
And then fuzzed the resulting binary using:
AFL_NO_VAR_CHECK=1 afl-fuzz -i in -o out bin/perl @@
After reducing testcases using `afl-tmin` and filtering out testcases that are merely iterations of "#!perl -u"\, I have located the following testcase that triggers a panic in the perl interpreter. The testcase is the 74-byte binary file: (octal bytes)
root@nagios:/usr/local/perl-afl/out# od -c allcrash/f2i000000 0000000 / 0 0 0 0 0 0 0 0 0 \ N { } 0 0 0000020 0 0 0 0 0 337 337 0 337 337 337 337 337 0 0 0 0000040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000060 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0000100 0 0 0 0 0 0 0 375 / i 0000112
I strongly suspect this is the same bug as 125990.
The base case of 125990 has enough ß (ss) characters for the generated string to take up the space for one extra regnode over the calculated length\, the case in this ticket overflows even further.
Your case doesn't produce an error (even with valgrind) on my 64-bit system\, but a modified (and shorter version) can be made to:
tony@mars:.../git/perl$ od -c ../125991b.pl 0000000 / \ N { } 337 337 337 337 337 337 337 337 337 337 337 0000020 375 / i 0000023
though it's only errors for me with valgrind.
I'm reasonably certain that this is a duplicate of another bug\, because I've seen the below sort of backtrace in a different bug\, that also related to a "creative" regular expression. However\, I can't find that bug. I'm also not sure if this is an upstream\, because Perl is trying to croak here\, and does so successfully under very similar circumstances.
When executed\, the following bad things happen:
root@nagios:/usr/local/perl-afl/out# ../bin/perl allcrash/f2i000000 *** glibc detected *** ../bin/perl: free(): invalid next size (normal): 0x0a3a2260 *** ======= Backtrace: ========= /lib/i686/cmov/libc.so.6(+0x6af71)[0xb7619f71] /lib/i686/cmov/libc.so.6(+0x6c7c8)[0xb761b7c8] /lib/i686/cmov/libc.so.6(+0x703ba)[0xb761f3ba] /lib/i686/cmov/libc.so.6(realloc+0xdd)[0xb761f97d] ../bin/perl(Perl_safesysrealloc+0xc8)[0x82d4ff8] ../bin/perl(Perl_sv_grow+0x4c4)[0x83dc5b4] ../bin/perl(Perl_sv_catpvn_flags+0x306)[0x83fbd76] ...
I expect this is caused by the buffer overflow from the above corrupting the malloc() arena.
**BISECT**
First commit that crashes in this particular way is: commit 75697d6e4ef98ece405210de48e7529d01b619bf Author: Karl Williamson \khw@​cpan\.org Date: Sun Dec 21 22:02:30 2014 -0700
Empty \N{} in regex pattern should force /d to /u
\N{} is for Unicode names\, even if the name is actually omitted. (Accepting an empty name is\, I believe\, an accident\, and now is supported only for backwards compatibility.)
While in this case it's \N{} forcing the regexp to be unicode\, other mechanisms can cause it too:
tony@mars:.../git/perl$ od -c ../125991c.pl 0000000 / \ p A 337 337 337 337 337 337 337 337 337 337 337 375 0000020 / i 0000022
Tony
The RT System itself - Status changed from 'new' to 'open'
On Tue Sep 08 08:04:55 2015\, public@khwilliamson.com wrote:
This is likely from my code\, so I'm taking the ticket to look at it.
Ok\, 125991 looks like the same bug (but a larger overflow that corrupts the memory arena).
Tony
Thanks for finding this.
I have figured out the cause\, and am now contemplating the best solution. Tony Cook was correct that #125990 and #125991 are from the same cause\, and so I have merged the two tickets.
This bug arises when a pattern is compiled under /id rules\, has a ß in it\, and has something else in it\, such as a \p or a \N{}\, that causes it to switch to /iu rules. The latter will try to fold the ß to 'ss'\, the former does not. Thus the latter takes up 2 bytes and the former takes up 1. The sizing pass is done under /id rules\, and the allocation pass is done under /iu\, so the space allocated is less than the space actually used\, and you get the problem.
Anything under compiled under 'use 5.012' or higher or 'use utf8' is by default compiled with /u rules\, so this bug won't likely appear in such code. One would have to explicitly say /d to override the default; this is unlikely.
Karl Williamson
Fixed by commit 512c0f5a351dd399dbb069e222741582044f88cc whose message is below:
This is a result of a design flaw that I introduced in earlier releases
when attempting to fix earlier design flaws in dealing with the outlier
character ß\, LATIN SMALL LETTER SHARP S. The uppercase of this letter
is SS\, so that when comparing case-insensitively\, it should match 'ss'\,
and hence\, in Unicode terminology\, it folds to 'ss'. This character is
the only one representable without using UTF-8 whose fold is longer than
1 byte\, and so has to have special treatment. Similarly\, the sequence
'ss' can match caselessly the single byte ß\, and this is the only such
sequence that can match something shorter than it\, unless UTF-8 is
involved. The matter is complicated by the fact that under /di rules\,
the ß and 'ss' don't match each other\, unless the target string is in
UTF-8. The solution I used earlier (and continue to use) was to create
a special regnode EXACTFU_SS under /ui rules\, in which any ß is folded
to 'ss'. But under /di rules\, a regular EXACTF regnode is used\, and any
ß is retained as-is.
The problem reported here arises when something during the sizing pass
tells perl to use /ui rules rather than the /di rules that were in
effect at the beginning. Recall that perl uses /d rules\, for backward
compatibility\, unless something overrides them. This can be a 'use'
declaration\, an explicit character set pattern modifier\, or something in
the pattern. This bug happens only with the final case. There are
several Unicode-defined constructs that can occur in patterns; if one is
found\, the perl interpreter infers that Unicode is desired\, and switches
from /d to /u for the whole pattern. Two such constructs are a Unicode
property\, \p{}\, and a Unicode named character\, \N{}. The
problem-reproducing code for this ticket uses the latter.
The problem was that the switch from /di to /ui was deferred until AFTER
the sizing pass. (A flag was set when one of these constructs was
encountered to tell the parser to later do the switch.)
During the second pass\, the code realizes it is under /ui\, so creates an
EXACTFU_SS node and folds the ß into 'ss'. But the first pass thought
it was under /di\, so it sized for just the ß\, i.e.\, for 1 byte\, so we
exceed the allocated space and do a wild write. This may not cause a
problem if the malloc'd space had rounded-up and there were only a few
of these ß characters.
One solution I considered was just keeping a global count of the ß
characters in EXACTF nodes. One could just add these to the space
reserved if /ui rules ended up being used. The problem with this is that
nodes that are near their maximum size without the extra space could
exceed it with\, and thus have to be split into 2 nodes\, and the extra
node would have an unplanned-for header\, taking up more unaccounted-for
space. So that doesn't work. One could also just reserve two bytes for
every ß in an EXACTF node\, thus wasting space unless /ui ends up being
used. But the bigger problem is that the code that splits nodes would
have to be made more complicated. It has to find a suitable splitting
spot\, by searching through the text of the node\, and now it would have
to deal with some of that space not being set.
Instead\, I opted to change the code so that when it finds one of these
Unicode-defined constructs\, it switches to /u immediately during the
sizing pass. That means that the parse afterwards knows that it is /u
and allocates the correct space. (We now have to remain in /u for the
remainder of the pass\, so some code had to change that reverted this.)
This fixes the test case in the ticket. But there remains a problem if
the sizing has happened earlier in the parse before the construct that
changes from /d to /u is encountered. Like:
qr/.....ß....\N{}/di
The incorrect sizing has already happened by the time the \N{} is
encountered. One could solve this by restarting the parse whenever the
/d goes to /u (under /i\, as this issue isn't a problem except when
folding ß). That slows things down. Instead\, I opted to set a global
flag whenever a ß is found in an EXACTF node. If that flag isn't set at
the time of the /d to /u switch\, there's no need to restart the parse.
A 'use utf8' or 'use 5.012' or higher selects /u over /d\, so the problem
did not happen with them\, nor if the pattern has to be converted to
UTF-8\, which restarts the sizing pass\, and it only happens with the
sharp s character. And probably unless there a several ß characters\,
the rounding-up of malloc space\, would cause this to not be an issue.
These explain why this hasn't been reported from the field.
--
Karl Williamson
@khwilliamson - Status changed from 'open' to 'pending release'
Thank you for submitting this report. You have helped make Perl better.
With the release of Perl 5.24.0 on May 9\, 2016\, this and 149 other issues have been resolved.
Perl 5.24.0 may be downloaded via https://metacpan.org/release/RJBS/perl-5.24.0
@khwilliamson - Status changed from 'pending release' to 'resolved'
Migrated from rt.perl.org#125990 (status was 'resolved')
Searchable as RT125990$