In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/655f5b268af8bf50c44ba4ae4803a33c9b792b8b?hp=f21038656da352686689ac9b4c5197596eba771d>

- Log -----------------------------------------------------------------
commit 655f5b268af8bf50c44ba4ae4803a33c9b792b8b
Author: David Mitchell <[email protected]>
Date:   Tue Mar 14 09:19:15 2017 +0000

    S_require_tie_mod(): use a new stack
    
    RT #130861
    
    This function is used to load a module associated with various magic vars,
    like $[ and %+. Since it can be called 'unexpectedly', it should use a new
    stack. The issue in this ticket was equivalent to
    
        my $var = '[';
        $$var;
    
    where the symbolic dereference triggered a run-time load of arybase.pm,
    which grew the stack, invalidating the SP in pp_rv2sv.
    
    Note that most of the stuff which S_require_tie_mod() calls, such as
    load_module(), will do its own PUSHSTACK(); but S_require_tie_mod() also
    does a bit of stack manipulation itself.
    
    The test case includes a magic number, 125, which happens to be the exact
    size necessary to trigger a stack realloc in S_require_tie_mod(). In later
    perl versions this value may well change. But it seemed too expensive
    to call fresh_perl_is() 100's of times with different values of $n.
    
    This commit also adds a SPAGAIN to pp_rv2sv on the 'belt and braces'
    principle.
    
    This commit is based on an earlier effort by Aaron Crane.
-----------------------------------------------------------------------

Summary of changes:
 gv.c       |  2 ++
 pp.c       |  1 +
 t/op/ref.t | 20 +++++++++++++++++++-
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gv.c b/gv.c
index 81fa5de631..ea41e78725 100644
--- a/gv.c
+++ b/gv.c
@@ -1339,6 +1339,7 @@ S_require_tie_mod(pTHX_ GV *gv, const char varname, const 
char * name,
       GV **gvp;
       dSP;
 
+      PUSHSTACKi(PERLSI_MAGIC);
       ENTER;
 
 #define HV_FETCH_TIE_FUNC (GV **)hv_fetchs(stash, "_tie_it", 0)
@@ -1368,6 +1369,7 @@ S_require_tie_mod(pTHX_ GV *gv, const char varname, const 
char * name,
       PUTBACK;
       call_sv((SV *)*gvp, G_VOID|G_DISCARD);
       LEAVE;
+      POPSTACK;
     }
 }
 
diff --git a/pp.c b/pp.c
index 6df21011af..53055217fd 100644
--- a/pp.c
+++ b/pp.c
@@ -403,6 +403,7 @@ PP(pp_rv2sv)
        else if (PL_op->op_private & OPpDEREF)
            sv = vivify_ref(sv, PL_op->op_private & OPpDEREF);
     }
+    SPAGAIN; /* in case chasing soft refs reallocated the stack */
     SETs(sv);
     RETURN;
 }
diff --git a/t/op/ref.t b/t/op/ref.t
index 65d50b67a2..44047ae17b 100644
--- a/t/op/ref.t
+++ b/t/op/ref.t
@@ -8,7 +8,7 @@ BEGIN {
 
 use strict qw(refs subs);
 
-plan(236);
+plan(237);
 
 # Test this first before we extend the stack with other operations.
 # This caused an asan failure due to a bad write past the end of the stack.
@@ -820,6 +820,24 @@ for ("4eounthouonth") {
        '[perl #109746] referential identity of \literal under threads+mad'
 }
 
+# RT#130861: heap-use-after-free in pp_rv2sv, from asan fuzzing
+SKIP: {
+    skip_if_miniperl("no dynamic loading on miniperl, so can't load arybase", 
1);
+    # this value is critical - its just enough so that the stack gets
+    # grown which loading/calling arybase
+    my $n = 125;
+
+    my $code = <<'EOF';
+$ary = '[';
+my @a = map $$ary, 1..NNN;
+print "@a\n";
+EOF
+    $code =~ s/NNN/$n/g;
+    my @exp = ("0") x $n;
+    fresh_perl_is($code, "@exp", { stderr => 1 },
+                    'rt#130861: heap uaf in pp_rv2sv');
+}
+
 # Bit of a hack to make test.pl happy. There are 3 more tests after it leaves.
 $test = curr_test();
 curr_test($test + 3);

--
Perl5 Master Repository

Reply via email to