Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assertion failure in S_maybe_multideref (op.c:14912) #16969

Closed
p5pRT opened this issue Apr 18, 2019 · 7 comments
Closed

Assertion failure in S_maybe_multideref (op.c:14912) #16969

p5pRT opened this issue Apr 18, 2019 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 18, 2019

Migrated from rt.perl.org#134045 (status was 'pending release')

Searchable as RT134045$

@p5pRT
Copy link
Author

p5pRT commented Apr 18, 2019

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 program

0for%{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​:126

This 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 +0100

  Add 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/zsh

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2019

From @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 program

0for%{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​:126

This 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 +0100

Add 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

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2019

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

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2019

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

@p5pRT
Copy link
Author

p5pRT commented May 25, 2019

From @dur-randir

Can this patch be applied now?

@p5pRT
Copy link
Author

p5pRT commented Jun 3, 2019

From @tonycoz

On Sat, 25 May 2019 08​:17​:43 -0700, randir wrote​:

Can this patch be applied now?

Applied as 94a2f6a, thanks for the report.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jun 3, 2019

@tonycoz - Status changed from 'open' to 'pending release'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant