develooper Front page | perl.perl5.porters | Postings from March 2017

[perl #129288] null ptr deref, segfault in S_rv2gv (pp.c:296)

Thread Previous
From:
Father Chrysostomos via RT
Date:
March 29, 2017 02:10
Subject:
[perl #129288] null ptr deref, segfault in S_rv2gv (pp.c:296)
Message ID:
rt-4.0.24-17149-1490753414-1512.129288-15-0@perl.org
On Tue, 28 Mar 2017 08:33:20 -0700, davem wrote:
> On Fri, Jan 27, 2017 at 06:52:50AM +0000, Zefram wrote:
> > The test case no longer segvs for me, since v5.25.6-78-g8b0c337.
> 
> The code can be reduced to:
> 
>     $x = "foo";
>     %:: = ($x);
>     *$x;
> 
> prior to that commit, pp_assign when assigning to a hash with an odd
> number of elements on the RHS, ended up using PL_sv_undef as the hash
> value rather than a copy of PL_sv_undef. PL_sv_undef as a value in a stash
> apparently means something special, so the glob lookup, *$x, crashed.
> 
> That commit fixed the bug of storing PL_sv_undef; I'm not sure whether
> there's still a bug of *$x crashing if $::{$x} is a pointer to
> PL_sv_undef - whether that is legal value etc.

Then one can still make it crash:

use feature "refaliasing";
\$::{foo} = \undef;
*{"foo"};

$ pbpaste|./perl -Ilib
Aliasing via reference is experimental at - line 2.
Segmentation fault: 11

> Basically the gv_fetchsv_nomg() call in S_rv2gv() returns NULL, which
> S_rv2gv() isn't expecting.
> 
> Perl_gv_fetchpvn_flags() has:
> 
>     gvp = (GV**)hv_fetch(stash,name,is_utf8 ? -(I32)len : (I32)len,add);
>     if (!gvp || *gvp == (const GV *)&PL_sv_undef) {
> 	if (addmg) gv = (GV *)newSV(0);
> 	else return NULL;
> 
> which is where the test for the magic value PL_sv_undef appears.

And that seems to be ancient.  However, I don’t know what would be logical to do otherwise.

Interestingly, other immortals are also, but differently, problematic.

use feature "refaliasing";
\$::{foo} = \!1;
*{"foo"};

Aliasing via reference is experimental at - line 2.
Assertion failed: (!SvPOKp(gv)), function Perl_gv_init_pvn, file gv.c, line 411.
Abort trap: 6

Perhaps they should just behave like this instead:

use feature "refaliasing";
\$::{foo} = \"foo";
*{"foo"};

$ pbpaste|./perl -Ilib
Aliasing via reference is experimental at - line 2.
Modification of a read-only value attempted at - line 3.

But the error message there is not all that helpful in saying what went wrong.

Maybe we could change croak_no_modify to include the op description.  (How much would that break?)

-- 

Father Chrysostomos


---
via perlbug:  queue: perl5 status: open
https://rt.perl.org/Ticket/Display.html?id=129288

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About