Assertion failure in S_maybe_multideref (op.c:14912) #16969
Description
Activity
From @dur-randir
Created by @dur-randir
While fuzzing perl v5.29.9-63-g2496d8f3f7 built with afl and run
under libdislocator, I found the following program0for%{scalar local$0[0]}
to cause an assertion failure
perl: op.c:14912: void S_maybe_multideref(OP *, OP *, UV, U8):
Assertion `n && n->op_type == OP_LEAVE' failed.GDB stack trace is following
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff7c25535 in __GI_abort () at abort.c:79
#2 0x00007ffff7c2540f in __assert_fail_base (fmt=0x7ffff7d87ee0
"%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
assertion=0x55555592a9c3 "n && n->op_type == OP_LEAVE",
file=0x5555559247ae "op.c", line=14892, function=<optimized out>) at
assert.c:92
#3 0x00007ffff7c330f2 in __GI___assert_fail (assertion=0x55555592a9c3
"n && n->op_type == OP_LEAVE", file=0x5555559247ae "op.c", line=14892,
function=0x55555592ccc0 <__PRETTY_FUNCTION__.22939>
"S_maybe_multideref") at assert.c:101
#4 0x00005555555deedc in S_maybe_multideref (start=0x555555b79648,
orig_o=0x555555b795c8, orig_action=6, hints=0 '\000') at op.c:14892
#5 0x00005555555e0146 in Perl_rpeep (o=0x555555b79648) at op.c:15545
#6 0x00005555555e37da in Perl_peep (o=0x555555b7b358) at op.c:16627
#7 0x00005555555ac110 in S_process_optree (cv=0x0,
optree=0x555555b7b390, start=0x555555b7b358) at op.c:3459
#8 0x00005555555b3f02 in Perl_newPROG (o=0x555555b7b390) at op.c:5413
#9 0x000055555566c1b0 in Perl_yyparse (gramtype=258) at perly.y:125
#10 0x00005555555ec726 in S_parse_body (env=0x0, xsinit=0x5555555a11f8
<xs_init>) at perl.c:2531
#11 0x00005555555ea9f8 in perl_parse (my_perl=0x555555b4e260,
xsinit=0x5555555a11f8 <xs_init>, argc=3, argv=0x7fffffffe1b8, env=0x0)
at perl.c:1822
#12 0x00005555555a113b in main (argc=3, argv=0x7fffffffe1b8,
env=0x7fffffffe1d8) at perlmain.c:126This is a regression between 5.20 and 5.22, bisect points to
commit fedf30e
Author: David Mitchell <davem@iabyn.com>
Date: Fri Oct 24 16:26:38 2014 +0100Add OP_MULTIDEREF
This op is an optimisation for any series of one or more array or hash
lookups and dereferences, where the key/index is a simple constant or
package/lexical variable. If the first-level lookup is of a simple
array/hash variable or scalar ref, then that is included in the op too.Perl Info
Flags: category=core severity=low 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/zshFrom @tonycoz
On Thu, 18 Apr 2019 09:51:12 -0700, randir wrote:
While fuzzing perl v5.29.9-63-g2496d8f3f7 built with afl and run
under libdislocator, I found the following program0for%{scalar local$0[0]}
to cause an assertion failure
perl: op.c:14912: void S_maybe_multideref(OP *, OP *, UV, U8):
Assertion `n && n->op_type == OP_LEAVE' failed.GDB stack trace is following
#0 __GI_raise (sig=sig@entry=6) at
../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff7c25535 in __GI_abort () at abort.c:79
#2 0x00007ffff7c2540f in __assert_fail_base (fmt=0x7ffff7d87ee0
"%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
assertion=0x55555592a9c3 "n && n->op_type == OP_LEAVE",
file=0x5555559247ae "op.c", line=14892, function=<optimized out>) at
assert.c:92
#3 0x00007ffff7c330f2 in __GI___assert_fail (assertion=0x55555592a9c3
"n && n->op_type == OP_LEAVE", file=0x5555559247ae "op.c", line=14892,
function=0x55555592ccc0 <__PRETTY_FUNCTION__.22939>
"S_maybe_multideref") at assert.c:101
#4 0x00005555555deedc in S_maybe_multideref (start=0x555555b79648,
orig_o=0x555555b795c8, orig_action=6, hints=0 '\000') at op.c:14892
#5 0x00005555555e0146 in Perl_rpeep (o=0x555555b79648) at op.c:15545
#6 0x00005555555e37da in Perl_peep (o=0x555555b7b358) at op.c:16627
#7 0x00005555555ac110 in S_process_optree (cv=0x0,
optree=0x555555b7b390, start=0x555555b7b358) at op.c:3459
#8 0x00005555555b3f02 in Perl_newPROG (o=0x555555b7b390) at op.c:5413
#9 0x000055555566c1b0 in Perl_yyparse (gramtype=258) at perly.y:125
#10 0x00005555555ec726 in S_parse_body (env=0x0, xsinit=0x5555555a11f8
<xs_init>) at perl.c:2531
#11 0x00005555555ea9f8 in perl_parse (my_perl=0x555555b4e260,
xsinit=0x5555555a11f8 <xs_init>, argc=3, argv=0x7fffffffe1b8, env=0x0)
at perl.c:1822
#12 0x00005555555a113b in main (argc=3, argv=0x7fffffffe1b8,
env=0x7fffffffe1d8) at perlmain.c:126This is a regression between 5.20 and 5.22, bisect points to
commit fedf30e
Author: David Mitchell <davem@iabyn.com>
Date: Fri Oct 24 16:26:38 2014 +0100Add OP_MULTIDEREF
This op is an optimisation for any series of one or more array or hash
lookups and dereferences, where the key/index is a simple constant or
package/lexical variable. If the first-level lookup is of a simple
array/hash variable or scalar ref, then that is included in the op
too.I think the check here should be bypassing the OP_SCALAR as it does OP_LIST.
Per the attached.
Tony
From @tonycoz
0001-perl-134048-prevent-an-erroneous-assertion-on-OP_SCA.patch
From d5eb166fb069cc1d53da26788049bf715cf68ba2 Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Wed, 24 Apr 2019 11:05:21 +1000 Subject: (perl #134048) prevent an erroneous assertion on OP_SCALAR --- op.c | 3 ++- t/op/multideref.t | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/op.c b/op.c index 1862f1b11b..a4bed9c582 100644 --- a/op.c +++ b/op.c @@ -14907,7 +14907,8 @@ S_maybe_multideref(pTHX_ OP *start, OP *orig_o, UV orig_action, U8 hints) #ifdef DEBUGGING OP *n = o->op_next; while (n && ( n->op_type == OP_NULL - || n->op_type == OP_LIST)) + || n->op_type == OP_LIST + || n->op_type == OP_SCALAR)) n = n->op_next; assert(n && n->op_type == OP_LEAVE); #endif diff --git a/t/op/multideref.t b/t/op/multideref.t index 12b04536e5..23487ca283 100644 --- a/t/op/multideref.t +++ b/t/op/multideref.t @@ -18,7 +18,7 @@ BEGIN { use warnings; use strict; -plan 64; +plan 65; # check that strict refs hint is handled @@ -242,3 +242,5 @@ sub defer {} ::pass("S_maybe_multideref() shouldn't leak on croak"); } +fresh_perl_is('0for%{scalar local$0[0]}', '', {}, + "RT #134045 assertion on the OP_SCALAR"); -- 2.11.0
The RT System itself - Status changed from 'new' to 'open'
From @dur-randir
Can this patch be applied now?
@tonycoz - Status changed from 'open' to 'pending release'
Migrated from rt.perl.org#134045 (status was 'pending release')
Searchable as RT134045$