summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2014-03-07 17:45:27 +0000
committerDavid Mitchell <davem@iabyn.com>2014-03-07 17:45:27 +0000
commit339441efdfcbaef5dbf131db2224abb35f5ae920 (patch)
treec5f5b4226dbf847ba56319b61a0f9dc67573622f /gv.c
parent70bc21b7ad97027997a11a7f2426306cb48874e3 (diff)
downloadperl-339441efdfcbaef5dbf131db2224abb35f5ae920.tar.gz
make core safe against HvAUX() realloc
Since the HvAUX structure is just tacked onto the end of the HvARRAY() struct, code like this can do bad things: aux = HvAUX(); ... something that might split hv ... aux->foo = ...; /* SEGV! */ So I've visually audited core for places where HbAUX() is saved and then re-used, and re-initialised the var if it looks like HvARRAY() could have changed in the meantime. I've been very conservative about what might be unsafe. For example, destructors or __WARN__ handlers could call perl code that modifies the hash.
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/gv.c b/gv.c
index ec052845b9..e402f6bf72 100644
--- a/gv.c
+++ b/gv.c
@@ -2263,7 +2263,6 @@ Perl_gv_check(pTHX_ HV *stash)
{
dVAR;
I32 i;
- struct xpvhv_aux *aux;
PERL_ARGS_ASSERT_GV_CHECK;
@@ -2271,12 +2270,11 @@ Perl_gv_check(pTHX_ HV *stash)
return;
assert(SvOOK(stash));
- aux = HvAUX(stash);
for (i = 0; i <= (I32) HvMAX(stash); i++) {
const HE *entry;
/* mark stash is being scanned, to avoid recursing */
- aux->xhv_aux_flags |= HvAUXf_SCAN_STASH;
+ HvAUX(stash)->xhv_aux_flags |= HvAUXf_SCAN_STASH;
for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) {
GV *gv;
HV *hv;
@@ -2310,7 +2308,7 @@ Perl_gv_check(pTHX_ HV *stash)
HEKfARG(GvNAME_HEK(gv)));
}
}
- aux->xhv_aux_flags &= ~HvAUXf_SCAN_STASH;
+ HvAUX(stash)->xhv_aux_flags &= ~HvAUXf_SCAN_STASH;
}
}
@@ -2493,7 +2491,6 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
{
int filled = 0;
int i;
- struct xpvhv_aux *aux;
bool deref_seen = 0;
@@ -2527,9 +2524,8 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
}
assert(SvOOK(stash));
- aux = HvAUX(stash);
/* initially assume the worst */
- aux->xhv_aux_flags &= ~HvAUXf_NO_DEREF;
+ HvAUX(stash)->xhv_aux_flags &= ~HvAUXf_NO_DEREF;
for (i = 1; i < NofAMmeth; i++) {
const char * const cooky = PL_AMG_names[i];