Skip to content

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

Description

@p5pRT

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

Searchable as RT134045$

Activity

  1. p5pRT commented on Apr 18, 2019

    @p5pRT
    Author

    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
    
    
  2. p5pRT commented on Apr 24, 2019

    @p5pRT
    Author

    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

  3. p5pRT commented on Apr 24, 2019

    @p5pRT
    Author

    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
    
    
  4. p5pRT commented on Apr 24, 2019

    @p5pRT
    Author

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

  5. p5pRT commented on May 25, 2019

    @p5pRT
    Author

    From @dur-randir

    Can this patch be applied now?

  6. p5pRT commented on Jun 3, 2019

    @p5pRT
    Author

    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

  7. p5pRT commented on Jun 3, 2019

    @p5pRT
    Author

    @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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions