diff options
author | David Mitchell <davem@iabyn.com> | 2014-03-07 17:45:27 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2014-03-07 17:45:27 +0000 |
commit | 339441efdfcbaef5dbf131db2224abb35f5ae920 (patch) | |
tree | c5f5b4226dbf847ba56319b61a0f9dc67573622f /gv.c | |
parent | 70bc21b7ad97027997a11a7f2426306cb48874e3 (diff) | |
download | perl-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.c | 10 |
1 files changed, 3 insertions, 7 deletions
@@ -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]; |