Skip Menu |

This queue is for tickets about the Scope-Cleanup CPAN distribution.

Report information
The Basics
Id: 91872
Status: resolved
Priority: 0/
Queue: Scope-Cleanup

People
Owner: Nobody in particular
Requestors: 'spro^^*%*^6ut# [...] &$%*c
Cc: SREZIC [...] cpan.org
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Existing stacks are not protected against reallocation.
pp_leavesub does this: POPSUB(cx,sv); before this: return cx->blk_sub.retop; Since POPSUB does LEAVE_SCOPE, it may call a destructor registered by establish_cleanup. That destructor will call run_cleanup, which does call_sv, which indirectly calls pp_entersub, which does PUSHBLOCK, which does CXINC, which may reallocate the context stack. So cx in the outer pp_leavesub call may end up pointing to freed-and- reused memory by the time the ‘return cx->blk_sub.retop’ is reached. I discovered this when working on PERL_DEBUG_READONLY_COW. ext/XS-APItest/t/cleanup.t was failing. In this case, the former con- text stack had been reused for some freshly allocated and zeroed mem- ory, so pp_leavesub returned NULL, causing the program to exit. I am about to extend STRESS_REALLOC in the perl core to force a reallocation in Perl_cxinc (as I did with the argument stack in 865e3ae09). This causes ext/XS-APItest/t/cleanup.t to fail under -DPERL_POISON + -DSTRESS_REALLOC + threads, which was the intent. So I am updating XS::APItest to account, like this: diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs index a4b91f6..4234469 100644 --- a/ext/XS-APItest/APItest.xs +++ b/ext/XS-APItest/APItest.xs @@ -533,12 +533,14 @@ STATIC void THX_run_cleanup(pTHX_ void *cleanup_code_ref) { dSP; + PUSHSTACK; ENTER; SAVETMPS; PUSHMARK(SP); call_sv((SV*)cleanup_code_ref, G_VOID|G_DISCARD); FREETMPS; LEAVE; + POPSTACK; } (The commit, on the sprout/realloc branch, won’t land in blead for a while, because POISON + STRESS_REALLOC is a very slow combination. I left it running overnight, and it is still compiling Encode and run- ning mktables.) I imagine Scope::Cleanup will fail under that configuration, too (since it has the same code), but I have not tested it.
Subject: Re: [rt.cpan.org #91872] Existing stacks are not protected against reallocation.
Date: Wed, 15 Jul 2015 11:37:08 +0100
To: Father Chrysostomos via RT <bug-Scope-Cleanup [...] rt.cpan.org>
From: Zefram <zefram [...] fysh.org>
Trelane has pointed me at a patch from rafl: --- lib/Scope/Cleanup.xs.orig 2015-07-14 16:48:36.036584445 -0500 +++ lib/Scope/Cleanup.xs 2015-07-14 16:49:15.244460784 -0500 @@ -14,24 +14,24 @@ static void run_cleanup(pTHX_ void *cleanup_code_ref) { + dSP; #if Q_MUST_PRESERVE_GHOST_CONTEXT bool have_ghost_context; PERL_CONTEXT ghost_context; have_ghost_context = cxstack_ix < cxstack_max; if(have_ghost_context) ghost_context = cxstack[cxstack_ix+1]; #endif /* Q_MUST_PRESERVE_GHOST_CONTEXT */ + PUSHSTACK; ENTER; SAVETMPS; - { - dSP; - PUSHMARK(SP); - } + PUSHMARK(SP); call_sv((SV*)cleanup_code_ref, G_VOID|G_DISCARD); #if Q_MUST_PRESERVE_GHOST_CONTEXT if(have_ghost_context) cxstack[cxstack_ix+1] = ghost_context; #endif /* Q_MUST_PRESERVE_GHOST_CONTEXT */ FREETMPS; LEAVE; + POPSTACK; } static OP *pp_establish_cleanup(pTHX) -zefram
RT-Send-CC: zefram [...] fysh.org
I've also written a test case for this issue, which I'm attaching. The previous patch makes the test pass. I'm not sure how reliable the test actually causes the stack reallocation to happen. I've tested on a couple of platforms and configurations, and it'd always trigger the bug, but I don't think anything guarantees it happening.
Subject: stack_realloc.t
use warnings; use strict; use Test::More tests => 3; BEGIN { use_ok "Scope::Cleanup", qw(establish_cleanup); } establish_cleanup sub { sub { pass }->((42) x 100_000); }; pass;
Fixed in Scope-Cleanup-0.003, just uploaded to CPAN.