Skip Menu |
Report information
Id: 126042
Status: open
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: dcollinsn [at] gmail.com
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: low
Type: unknown
Perl Version: (no value)
Fixed In: (no value)

Attachments
0001-perl-126042-handle-scalar-context-for-a-missing-impo.patch



Subject: Segmentation fault in Perl_pp_multiply (and other functions)
Download (untitled) / with headers
text/plain 5.2k
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 -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 segmentation fault in the perl interpreter. The testcase is the 15-byte file: &{0==0}*&{0==0} Several other variations of this failed, but this is the simplest example. All have either two calls to "&{0==0}" or nested calls of that type "&{0==&{0==0}}". This looks vaguely similar to the bugs arising from the stack not being refcounted (c.f. 125840, 123710, 123804, 123997, but the failure point is different. Unfortunately, no valgrind is available, as I haven't yet had a chance to upgrade to a version of valgrind that's aware of dwarf 4 and I'm off to work. If you for whatever reason are unable to repro this, I'll try to add updated information early this week. **GDB** GNU gdb (GDB) 7.10 Copyright (C) 2015 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ../bin/perl...done. (gdb) run Starting program: /usr/local/perl-afl/bin/perl f4i000000 [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x083ff152 in Perl_pp_multiply () at pp.c:1275 1275 tryAMAGICbin_MG(mult_amg, AMGf_assign|AMGf_numeric); (gdb) bt #0 0x083ff152 in Perl_pp_multiply () at pp.c:1275 #1 0x083506fb in Perl_runops_standard () at run.c:41 #2 0x08116c47 in S_run_body (oldscope=1) at perl.c:2456 #3 perl_run (my_perl=0x87d8008) at perl.c:2379 #4 0x08068762 in main (argc=2, argv=0xbffff7e4, env=0xbffff7f0) at perlmain.c:116 **PERL -V** Summary of my perl5 (revision 5 version 23 subversion 3) configuration: Commit id: 718ac8a2e5fd26fa68078f057e7c332594ebebf6 Platform: osname=linux, osvers=2.6.32-5-686, archname=i686-linux-64int-ld 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=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef use64bitint=define, use64bitall=undef, uselongdouble=define usemymalloc=n, bincompat5005=undef Compiler: cc='afl-gcc', ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-g', cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include' ccversion='', gccversion='5.2.0', 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-strong -L/usr/local/lib' libpth=/usr/local/lib /usr/local/lib/gcc/i686-pc-linux-gnu/5.2.0/include-fixed /usr/lib /lib/../lib /usr/lib/../lib /lib /usr/lib/i486-linux-gnu /usr/lib64 libs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc libc=libc-2.22.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.22' 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-strong' Characteristics of this binary (from libperl): Compile-time options: HAS_TIMES PERLIO_LAYERS PERL_COPY_ON_WRITE PERL_DONT_CREATE_GVSV PERL_HASH_FUNC_ONE_AT_A_TIME_HARD PERL_MALLOC_WRAP PERL_PRESERVE_IVUV PERL_USE_DEVEL USE_64_BIT_INT 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 Built under linux Compiled at Sep 8 2015 22:24:21 @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 .
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 2.8k
%% VALGRIND OUTPUT FOR CANONICAL TESTCASE ABOVE %% ==6140== Memcheck, a memory error detector ==6140== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==6140== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==6140== Command: ../bin/perl f4i000000 ==6140== ==6140== Invalid read of size 4 ==6140== at 0x83FF4D9: Perl_pp_multiply (pp.c:1274) ==6140== by 0x83506FA: Perl_runops_standard (run.c:41) ==6140== by 0x8116C46: S_run_body (perl.c:2456) ==6140== by 0x8116C46: perl_run (perl.c:2379) ==6140== by 0x8068761: main (perlmain.c:116) ==6140== Address 0x42bffd4 is 4 bytes before a block of size 512 alloc'd ==6140== at 0x402A0DE: malloc (vg_replace_malloc.c:296) ==6140== by 0x82B3593: Perl_safesysmalloc (util.c:153) ==6140== by 0x83435E7: Perl_av_extend_guts (av.c:182) ==6140== by 0x834375F: Perl_av_extend (av.c:80) ==6140== by 0x845C97D: Perl_new_stackinfo (scope.c:56) ==6140== by 0x80FF36D: Perl_init_stacks (perl.c:4063) ==6140== by 0x80FF84D: perl_construct (perl.c:249) ==6140== by 0x80684B8: main (perlmain.c:110) ==6140== ==6140== Invalid read of size 4 ==6140== at 0x83FF152: Perl_pp_multiply (pp.c:1275) ==6140== by 0x83506FA: Perl_runops_standard (run.c:41) ==6140== by 0x8116C46: S_run_body (perl.c:2456) ==6140== by 0x8116C46: perl_run (perl.c:2379) ==6140== by 0x8068761: main (perlmain.c:116) ==6140== Address 0x8 is not stack'd, malloc'd or (recently) free'd ==6140== ==6140== ==6140== Process terminating with default action of signal 11 (SIGSEGV) ==6140== Access not within mapped region at address 0x8 ==6140== at 0x83FF152: Perl_pp_multiply (pp.c:1275) ==6140== by 0x83506FA: Perl_runops_standard (run.c:41) ==6140== by 0x8116C46: S_run_body (perl.c:2456) ==6140== by 0x8116C46: perl_run (perl.c:2379) ==6140== by 0x8068761: main (perlmain.c:116) ==6140== If you believe this happened as a result of a stack ==6140== overflow in your program's main thread (unlikely but ==6140== possible), you can try to increase the size of the ==6140== main thread stack using the --main-stacksize= flag. ==6140== The main thread stack size used in this run was 8388608. ==6140== ==6140== HEAP SUMMARY: ==6140== in use at exit: 87,294 bytes in 520 blocks ==6140== total heap usage: 618 allocs, 98 frees, 104,737 bytes allocated ==6140== ==6140== LEAK SUMMARY: ==6140== definitely lost: 80 bytes in 1 blocks ==6140== indirectly lost: 1,821 bytes in 18 blocks ==6140== possibly lost: 0 bytes in 0 blocks ==6140== still reachable: 85,393 bytes in 501 blocks ==6140== suppressed: 0 bytes in 0 blocks ==6140== Rerun with --leak-check=full to see details of leaked memory ==6140== ==6140== For counts of detected and suppressed errors, rerun with: -v ==6140== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) Segmentation fault
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 135b
For fun, some other examples of failing testcases after afl-tmin: &{0==&{0==0}}.0 &{0==0}/&{0==0}&0 &{0*&{0==0}==0}/0 &{0==0}*&{0==0}
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 610b
On Sat Sep 12 05:36:20 2015, dcollinsn@gmail.com wrote: Show quoted text
> &{0==0}*&{0==0} > > Several other variations of this failed, but this is the simplest > example. All have either two calls to "&{0==0}" or nested calls of > that type "&{0==&{0==0}}". This looks vaguely similar to the bugs > arising from the stack not being refcounted (c.f. 125840, 123710, > 123804, 123997, but the failure point is different.
No, it’s more like stack corruption (perl getting confused about where it’s stack pointer should be): $ ./miniperl -Ilib -le 'print 1, 2, 3,&{0==0}*&{0==0}, 4, 5, 6' 16456 -- Father Chrysostomos
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 993b
On Sun Sep 20 15:22:29 2015, sprout wrote: Show quoted text
> On Sat Sep 12 05:36:20 2015, dcollinsn@gmail.com wrote:
> > &{0==0}*&{0==0} > > > > Several other variations of this failed, but this is the simplest > > example. All have either two calls to "&{0==0}" or nested calls of > > that type "&{0==&{0==0}}". This looks vaguely similar to the bugs > > arising from the stack not being refcounted (c.f. 125840, 123710, > > 123804, 123997, but the failure point is different.
> > No, it’s more like stack corruption (perl getting confused about where > it’s stack pointer should be): > > $ ./miniperl -Ilib -le 'print 1, 2, 3,&{0==0}*&{0==0}, 4, 5, 6' > 16456
Specifically, it is related to the fact that PL_sv_yes->() silently does nothing, but its doing nothing is badly implemented. This whole PL_sv_yes call thing is wart resulting from implementation details. I wonder if we can just remove it from perl space. Surely nobody is relying on it! (Famous last words.) -- Father Chrysostomos
Date: Mon, 21 Sep 2015 12:35:26 +0100
Subject: Re: [perl #126042] Segmentation fault in Perl_pp_multiply (and other functions)
From: Zefram <zefram [...] fysh.org>
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 450b
Father Chrysostomos via RT wrote: Show quoted text
>This whole PL_sv_yes call thing is wart resulting from implementation >details. I wonder if we can just remove it from perl space.
We certainly should, because its exposure per se produces visible bugs: $ perl -lwe '*1 = sub { print @_; }; &1(2); &{!!1}(3)' 2 Even if its do-nothing behaviour were implemented correctly, it's wrong for it to behave differently from an ordinary 1 as a subroutine ref. -zefram
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 444b
On Sat Sep 12 05:36:20 2015, dcollinsn@gmail.com wrote: Show quoted text
> 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 segmentation fault in the perl > interpreter. The testcase is the 15-byte file: > > &{0==0}*&{0==0}
The attached fixes the handling of calls to &PL_sv_yes. I'm not sure how to approach eliminating the wart. Tony
Subject: 0001-perl-126042-handle-scalar-context-for-a-missing-impo.patch
From d3e254d742fc2792ecc5e19a1fa4f1a3fa79f57b Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Wed, 4 Nov 2015 11:03:36 +1100 Subject: [perl #126042] handle scalar context for a missing import/unimport call --- pp_hot.c | 2 ++ t/op/method.t | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pp_hot.c b/pp_hot.c index 87e306c..366828a 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -3275,6 +3275,8 @@ PP(pp_entersub) SP = PL_stack_base + POPMARK; else (void)POPMARK; + if (GIMME_V == G_SCALAR) + PUSHs(&PL_sv_undef); RETURN; } SvGETMAGIC(sv); diff --git a/t/op/method.t b/t/op/method.t index 1171f4a..0d7f254 100644 --- a/t/op/method.t +++ b/t/op/method.t @@ -13,7 +13,7 @@ BEGIN { use strict; no warnings 'once'; -plan(tests => 147); +plan(tests => 148); @A::ISA = 'B'; @B::ISA = 'C'; @@ -657,6 +657,23 @@ SKIP: { like ($@, qr/Modification of a read-only value attempted/, 'RT #123619'); } +{ + # RT #126042 &{1==1} * &{1==1} would crash + + # pp_entersub and pp_method_named cooperate to prevent calls to an + # undefined import() or unimport() method from croaking. + # If pp_method_named can't find the method it pushes &PL_sv_yes, and + # pp_entersub checks for that specific SV to avoid croaking. + # Ideally they wouldn't use that hack but... + # Unfortunately pp_entersub's handling of that case is broken in scalar context. + + # Rather than using the test case from the ticket, since &{1==1} + # isn't documented (and may not be supported in future perls) test + # calls to undefined import method, which also crashes. + fresh_perl_is('Unknown->import() * Unknown->unimport(); print "ok\n"', "ok\n", {}, + "check unknown import() methods don't corrupt the stack"); +} + __END__ #FF9900 #F78C08 -- 2.1.4
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 534b
On Tue Nov 03 16:17:43 2015, tonyc wrote: Show quoted text
> The attached fixes the handling of calls to &PL_sv_yes. > > I'm not sure how to approach eliminating the wart. > > Tony
That fix looks like it doesn't fix the problem. It needs to be fixed in the optree at compile tile, that multiply operator takes 1 argument, not empty list. There might be other ways to get rh and lh operands of multiply to be empty list and cause the same crash again without calling empty sub references (PL_sv_yes in this case). -- bulk88 ~ bulk88 at hotmail.com
Date: Wed, 4 Nov 2015 06:30:25 +0000
Subject: Re: [perl #126042] Segmentation fault in Perl_pp_multiply (and other functions)
From: Zefram <zefram [...] fysh.org>
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 429b
bulk88 via RT wrote: Show quoted text
>There might be other ways to get rh and lh operands of multiply to >be empty list and cause the same crash again
Any such way would be another bug. The operands of the multiply op are put into scalar context, and it is intended that every optree scalar-context optree will yield exactly one value on the stack. The magic subroutine behind &PL_sv_yes was erroneous in not obeying scalar context. -zefram
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 620b
On Tue Nov 03 16:17:43 2015, tonyc wrote: Show quoted text
> On Sat Sep 12 05:36:20 2015, dcollinsn@gmail.com wrote:
> > 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 segmentation fault in the perl > > interpreter. The testcase is the 15-byte file: > > > > &{0==0}*&{0==0}
> > The attached fixes the handling of calls to &PL_sv_yes.
Applied as 0cd52e23ae641a766983833dc8b37b743474be9e. Show quoted text
> I'm not sure how to approach eliminating the wart.
Leaving the ticket open in case someone figures that out. Tony
CC: perl5-porters [...] perl.org
To: Tony Cook via RT <perlbug-followup [...] perl.org>
Subject: Re: [perl #126042] Segmentation fault in Perl_pp_multiply (and other functions)
From: Dave Mitchell <davem [...] iabyn.com>
Date: Thu, 7 Jan 2016 13:04:42 +0000
Download (untitled) / with headers
text/plain 484b
On Wed, Jan 06, 2016 at 09:28:17PM -0800, Tony Cook via RT wrote: Show quoted text
> > I'm not sure how to approach eliminating the wart.
> > Leaving the ticket open in case someone figures that out.
Maybe make the method-locating code return a stub XS CV rather than PL_sv_yes when it fails to find "import"?, This XS sub would do whatever pp_entersub used to do when it encountered PL_sv_yes. -- "Procrastination grows to fill the available time" -- Mitchell's corollary to Parkinson's Law


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org