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

op.c:13184: S_maybe_multideref: Assertion `!(o->op_private & ~(0x03|0x30))' failed #15864

Closed
p5pRT opened this issue Feb 6, 2017 · 12 comments
Closed

Comments

@p5pRT
Copy link

p5pRT commented Feb 6, 2017

Migrated from rt.perl.org#130727 (status was 'resolved')

Searchable as RT130727$

@p5pRT
Copy link
Author

p5pRT commented Feb 6, 2017

From @dur-randir

Created by @dur-randir

While fuzzing perl v5.25.9-35-g32207c637b built with afl and run
under libdislocator, I found the following program

p$0[],%{[],local$0[0][0]}

to cause an assertion failure, even when run under -c for a syntax
check. GDB info about the crash location​:

(gdb) bt
#0 __GI_raise (sig=sig@​entry=6) at ../sysdeps/unix/sysv/linux/raise.c​:58
#1 0x00007f9cfcbaf40a in __GI_abort () at abort.c​:89
#2 0x00007f9cfcba6e47 in __assert_fail_base (fmt=<optimized out>,
assertion=assertion@​entry=0x7f9cfe23ecf8 "!(o->op_private &
~(0x03|0x30))",
  file=file@​entry=0x7f9cfe2392ae "op.c", line=line@​entry=13184,
function=function@​entry=0x7f9cfe2407a0 <__PRETTY_FUNCTION__.19575>
"S_maybe_multideref")
  at assert.c​:92
#3 0x00007f9cfcba6ef2 in __GI___assert_fail (assertion=0x7f9cfe23ecf8
"!(o->op_private & ~(0x03|0x30))", file=0x7f9cfe2392ae "op.c",
line=13184,
  function=0x7f9cfe2407a0 <__PRETTY_FUNCTION__.19575>
"S_maybe_multideref") at assert.c​:101
#4 0x00007f9cfdf1e1a5 in S_maybe_multideref (start=0x7f9d00335018,
orig_o=0x7f9d00334f98, orig_action=6, hints=0 '\000') at op.c​:13184
#5 0x00007f9cfdf1f2ea in Perl_rpeep (o=0x7f9d00335018) at op.c​:13771
#6 0x00007f9cfdf227ea in Perl_peep (o=0x7f9d00334be8) at op.c​:14786
#7 0x00007f9cfdeed5b1 in S_process_optree (cv=0x0,
optree=0x7f9d003330c0, start=0x7f9d00334be8) at op.c​:2475
#8 0x00007f9cfdef46a7 in Perl_newPROG (o=0x7f9d003330c0) at op.c​:4303
#9 0x00007f9cfdfa7eeb in Perl_yyparse (gramtype=258) at perly.y​:123
#10 0x00007f9cfdf2ab84 in S_parse_body (env=0x0, xsinit=0x7f9cfdee5fa8
<xs_init>) at perl.c​:2376
#11 0x00007f9cfdf28ee9 in perl_parse (my_perl=0x7f9d00312010,
xsinit=0x7f9cfdee5fa8 <xs_init>, argc=2, argv=0x7ffe6bfd88d8, env=0x0)
at perl.c​:1691
#12 0x00007f9cfdee5ee6 in main (argc=2, argv=0x7ffe6bfd88d8,
env=0x7ffe6bfd88f0) at perlmain.c​:121
(gdb) f 4
#4 0x00007f9cfdf1e1a5 in S_maybe_multideref (start=0x7f9d00335018,
orig_o=0x7f9d00334f98, orig_action=6, hints=0 '\000') at op.c​:13184
13184 ASSUME(!(o->op_private & ~(OPpARG2_MASK|OPpDEREF)));
(gdb) p o->op_private
$1 = 162 '\242'

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.25.9:

Configured by root at Sat Jan 14 02:25:05 MSK 2017.

Summary of my perl5 (revision 5 version 25 subversion 9) configuration:
  Commit id: cbe2fc5001aa59cdc73e04cc35e097a2ecfbeec0
  Platform:
    osname=linux
    osvers=3.16.0-4-amd64
    archname=x86_64-linux
    uname='linux dorothy 3.16.0-4-amd64 #1 smp debian 3.16.36-1+deb8u2
(2016-10-19) x86_64 gnulinux '
    config_args='-des -Dusedevel -DDEBUGGING -Dcc=afl-clang-fast
-Doptimize=-O0 -g -ggdb3'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=undef
    usemultiplicity=undef
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    bincompat5005=undef
  Compiler:
    cc='afl-clang-fast'
    ccflags ='-DDEBUGGING -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
    optimize='-O0 -g -ggdb3'
    cppflags='-DDEBUGGING -fno-strict-aliasing -pipe
-fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='4.2.1 Compatible Clang 3.9.1 (tags/RELEASE_391/rc2)'
    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='afl-clang-fast'
    ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/llvm-3.9/bin/../lib/clang/3.9.1/lib
/usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu
/lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
    libs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.24.so
    so=so
    useshrplib=false
    libperl=libperl.a
    gnulibc_version='2.24'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E'
    cccdlflags='-fPIC'
    lddlflags='-shared -O0 -g -ggdb3 -L/usr/local/lib -fstack-protector-strong'



@INC for perl 5.25.9:
    lib
    /usr/local/lib/perl5/site_perl/5.25.9/x86_64-linux
    /usr/local/lib/perl5/site_perl/5.25.9
    /usr/local/lib/perl5/5.25.9/x86_64-linux
    /usr/local/lib/perl5/5.25.9


Environment for perl 5.25.9:
    HOME=/home/afl
    LANG=en_US.UTF-8
    LANGUAGE=en_US:en
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/afl/perlbrew/bin:/home/afl/perlbrew/perls/perl-5.22.1/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
    PERLBREW_BASHRC_VERSION=0.78
    PERLBREW_HOME=/home/afl/.perlbrew
    PERLBREW_MANPATH=/home/afl/perlbrew/perls/perl-5.22.1/man
    PERLBREW_PATH=/home/afl/perlbrew/bin:/home/afl/perlbrew/perls/perl-5.22.1/bin
    PERLBREW_PERL=perl-5.22.1
    PERLBREW_ROOT=/home/afl/perlbrew
    PERLBREW_VERSION=0.78
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2017

From @hvds

On Mon, 06 Feb 2017 13​:21​:39 -0800, randir wrote​:

While fuzzing perl v5.25.9-35-g32207c637b built with afl and run
under libdislocator, I found the following program

p$0[],%{[],local$0[0][0]}

to cause an assertion failure, even when run under -c for a syntax
check.

This simplifies to​:

% ./miniperl -wle 'sub p { print for @​_ }; p($x[0], %{local $x[0]})'
miniperl​: op.c​:13184​: S_maybe_multideref​: Assertion `!(o->op_private & ~(0x03|0x30))' failed.
Aborted (core dumped)
%

The assert is complaining about OPpLVAL_INTRO set at op.c​:3328, and can also be triggered with eg '(local $x[0])->{x}' or '(local $x[0])->[0]'.

If I hack out the assert it happily does what appears to be the right thing (though I'm not sure about the first warning)​:

% ./hackedminiperl -wle 'sub p { print for @​_ } p($x[0], %{local $x[0]})'
Use of uninitialized value in hash dereference at -e line 1.
Use of uninitialized value $_ in print at -e line 1.

%

Without the local() we get to see the autovivified hashref, which I assume is also correct​:

% ./miniperl -wle 'sub p { print for @​_ } p($x[0], %{$x[0]})'
HASH(0x1ea15c0)
%

I don't know enough to suggest what should be changed here.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2017

From @iabyn

On Tue, Feb 07, 2017 at 04​:47​:09AM -0800, Hugo van der Sanden via RT wrote​:

On Mon, 06 Feb 2017 13​:21​:39 -0800, randir wrote​:

While fuzzing perl v5.25.9-35-g32207c637b built with afl and run
under libdislocator, I found the following program

p$0[],%{[],local$0[0][0]}

to cause an assertion failure, even when run under -c for a syntax
check.

This simplifies to​:

% ./miniperl -wle 'sub p { print for @​_ }; p($x[0], %{local $x[0]})'
miniperl​: op.c​:13184​: S_maybe_multideref​: Assertion `!(o->op_private & ~(0x03|0x30))' failed.
Aborted (core dumped)
%

The assert is complaining about OPpLVAL_INTRO set at op.c​:3328, and can also be triggered with eg '(local $x[0])->{x}' or '(local $x[0])->[0]'.

If I hack out the assert it happily does what appears to be the right thing (though I'm not sure about the first warning)​:

% ./hackedminiperl -wle 'sub p { print for @​_ } p($x[0], %{local $x[0]})'
Use of uninitialized value in hash dereference at -e line 1.
Use of uninitialized value $_ in print at -e line 1.

%

Without the local() we get to see the autovivified hashref, which I assume is also correct​:

% ./miniperl -wle 'sub p { print for @​_ } p($x[0], %{$x[0]})'
HASH(0x1ea15c0)
%

I don't know enough to suggest what should be changed here.

I'm currently working on this. Will update soon.

--
Monto Blanco... scorchio!

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2017

From @iabyn

On Tue, Feb 07, 2017 at 03​:07​:10PM +0000, Dave Mitchell wrote​:

I'm currently working on this. Will update soon.

I've just pushed this​:

commit 43dbb3c
Author​: David Mitchell <davem@​iabyn.com>
AuthorDate​: Tue Feb 7 15​:45​:14 2017 +0000
Commit​: David Mitchell <davem@​iabyn.com>
CommitDate​: Tue Feb 7 15​:46​:57 2017 +0000

  multideref​: handle both OPpLVAL_INTRO,OPpDEREF
 
  RT #130727
 
  In a nested dereference like $a[0]{b}[1], all but the last aelem/helem
  will normally have a OPpDEREF_AV/HV flag, while the last won't have a deref
  but may well have OPpLVAL_INTRO, e.g.
 
  local $a[0]{b}[1] = 1;
 
  The code in S_maybe_multideref() which converts a chain of aelem/helem's
  into a single mltideref op assumes this - in particular that an op can't
  have both OPpLVAL_INTRO and OPpDEREF* at the same time. However, the
  following code violates that assumption​:
 
  @​{ local $a[0]{b}[1] } = 1;
 
  In @​{expr} = 1, the array is in lvalue context, which makes expr be done
  in ref (autovivify) context. So the final aelem in the above expression
  gets both OPpLVAL_INTRO and OPpDEREF_AV flags.
 
  In the old days, pp_aelem (probably more by luck than design) would action
  OPpLVAL_INTRO and ignore OPpDEREF_AV. This commit makes pp_multideref
  behave in the same way. In particular, there's no point in autovivifying
  $a[0]{b}[1] as an array ref since the local() will be undone before it
  gets a change to be used.
 
  The easiest way to achieve this is to tun off the OPpDEREF flag on the
  aelem/helem op if the OPpLVAL_INTRO flag is set.

--
You're only as old as you look.

@p5pRT
Copy link
Author

p5pRT commented Feb 12, 2017

From @tonycoz

On Tue, 07 Feb 2017 08​:04​:36 -0800, davem wrote​:

On Tue, Feb 07, 2017 at 03​:07​:10PM +0000, Dave Mitchell wrote​:

I'm currently working on this. Will update soon.

I've just pushed this​:

commit 43dbb3c
Author​: David Mitchell <davem@​iabyn.com>
AuthorDate​: Tue Feb 7 15​:45​:14 2017 +0000
Commit​: David Mitchell <davem@​iabyn.com>
CommitDate​: Tue Feb 7 15​:46​:57 2017 +0000

Does that mean this ticket is closable?

Tony

@p5pRT
Copy link
Author

p5pRT commented Feb 15, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Feb 15, 2017

From @iabyn

On Sun, Feb 12, 2017 at 03​:45​:28PM -0800, Tony Cook via RT wrote​:

On Tue, 07 Feb 2017 08​:04​:36 -0800, davem wrote​:

On Tue, Feb 07, 2017 at 03​:07​:10PM +0000, Dave Mitchell wrote​:

I'm currently working on this. Will update soon.

I've just pushed this​:

commit 43dbb3c
Author​: David Mitchell <davem@​iabyn.com>
AuthorDate​: Tue Feb 7 15​:45​:14 2017 +0000
Commit​: David Mitchell <davem@​iabyn.com>
CommitDate​: Tue Feb 7 15​:46​:57 2017 +0000

Does that mean this ticket is closable?

Yes, I forgot to do that. Closed now.

--
A problem shared is a problem doubled.

@p5pRT
Copy link
Author

p5pRT commented Feb 16, 2017

From @dur-randir

On Wed, 15 Feb 2017 03​:21​:46 -0800, davem wrote​:

Yes, I forgot to do that. Closed now.

While this fixes cases deducted by Hugo van der Sanden and provided in your commit message, the original ./perl -e 'p$0[],%{[],local$0[0][0]}' still segfaults, though with another message​:

perl​: op.c​:13196​: void S_maybe_multideref(OP *, OP *, UV, U8)​: Assertion `o->op_next->op_type == OP_LEAVE' failed.

@p5pRT
Copy link
Author

p5pRT commented Feb 18, 2017

From @iabyn

On Thu, Feb 16, 2017 at 01​:27​:46PM -0800, Sergey Aleynikov via RT wrote​:

On Wed, 15 Feb 2017 03​:21​:46 -0800, davem wrote​:

Yes, I forgot to do that. Closed now.

While this fixes cases deducted by Hugo van der Sanden and provided in your commit message, the original ./perl -e 'p$0[],%{[],local$0[0][0]}' still segfaults, though with another message​:

perl​: op.c​:13196​: void S_maybe_multideref(OP *, OP *, UV, U8)​: Assertion `o->op_next->op_type == OP_LEAVE' failed.

Fixed by v5.25.9-154-gd8f2fe0

--
I don't want to achieve immortality through my work...
I want to achieve it through not dying.
  -- Woody Allen

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release today of Perl 5.26.0, this and 210 other issues have been
resolved.

Perl 5.26.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.26.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

@khwilliamson - Status changed from 'pending release' to 'resolved'

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