From 96258673547f51dc588c290d9c8ff3d9b2b93397 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Mon, 28 Apr 2014 11:50:20 +0100 Subject: [PATCH] Pseudo-fork dups arg array on argless calls RT #121721. A subroutine call like &foo; pushes a SUB context with the savearray field unassigned, and with CxHASARGS() false. Most of the core knows not to use this field without CxHASARGS() being true: except for Perl_cx_dup(), which was still trying to dup it. This could lead to SEGVs on a fresh CX stack, or possibly duping some other sub's @_ on a reused stack entry. The fix is simple; don't dup this field unless CxHASARGS() is set. Note that a similar test is already in place for the argarray field. --- sv.c | 6 ++++-- t/op/fork.t | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/sv.c b/sv.c index 087606b..85f91f1 100644 --- a/sv.c +++ b/sv.c @@ -12778,8 +12778,10 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param) ? av_dup_inc(ncx->blk_sub.argarray, param) : NULL); - ncx->blk_sub.savearray = av_dup_inc(ncx->blk_sub.savearray, - param); + ncx->blk_sub.savearray = (CxHASARGS(ncx) + ? av_dup_inc(ncx->blk_sub.savearray, + param) + : NULL); ncx->blk_sub.oldcomppad = (PAD*)ptr_table_fetch(PL_ptr_table, ncx->blk_sub.oldcomppad); break; diff --git a/t/op/fork.t b/t/op/fork.t index 0d93f5f..60c991b 100644 --- a/t/op/fork.t +++ b/t/op/fork.t @@ -505,3 +505,17 @@ EXPECT 2 3 4 +######## +# this used to SEGV. RT # 121721 +$|=1; +&main; +sub main { + if (my $pid = fork) { + waitpid($pid, 0); + } + else { + print "foo\n"; + } +} +EXPECT +foo -- 2.7.4