summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2021-07-26 07:32:46 +0000
committerNicholas Clark <nick@ccl4.org>2021-09-16 07:06:57 +0000
commitf15a20bce3aaf0956e466389530be470aa2cabfe (patch)
tree23ccb66f9917a7856ea7a3ef3b10f00623ba3b2c /hv.c
parentd5a0a5dd15db7407246717e8c3e8891b9ba7c53c (diff)
downloadperl-f15a20bce3aaf0956e466389530be470aa2cabfe.tar.gz
Avoid a use-after-free deleting 8-bit keys from stashes
This code path only affects symbol tables, and can't be reached by regular Perl code. It is only reachable using the XS API to delete a key from a stash where the key was in the 8-bit range but passed in UTF-8 encoded. This has been in the code since it was added in Oct 2010 by commit 35759254f69c7bfa: Rename stashes when they move around Also there is no need to call SvPV() on keysv in S_hv_delete_common() as its caller has always already done this. This entire code is not KISS.
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/hv.c b/hv.c
index 35e14d6498..3dece08a6d 100644
--- a/hv.c
+++ b/hv.c
@@ -1256,15 +1256,12 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
"Attempt to delete readonly key '%" SVf "' from"
" a restricted hash");
}
- if (k_flags & HVhek_FREEKEY)
- Safefree(key);
/* If this is a stash and the key ends with ::, then someone is
* deleting a package.
*/
if (HeVAL(entry) && HvENAME_get(hv)) {
gv = (GV *)HeVAL(entry);
- if (keysv) key = SvPV(keysv, klen);
if ((
(klen > 1 && key[klen-2] == ':' && key[klen-1] == ':')
||
@@ -1353,6 +1350,9 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
}
}
+ if (k_flags & HVhek_FREEKEY)
+ Safefree(key);
+
sv = d_flags & G_DISCARD ? HeVAL(entry) : sv_2mortal(HeVAL(entry));
HeVAL(entry) = &PL_sv_placeholder;
if (sv) {