diff options
author | Nicholas Clark <nick@ccl4.org> | 2021-07-26 07:32:46 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2021-09-16 07:06:57 +0000 |
commit | f15a20bce3aaf0956e466389530be470aa2cabfe (patch) | |
tree | 23ccb66f9917a7856ea7a3ef3b10f00623ba3b2c /hv.c | |
parent | d5a0a5dd15db7407246717e8c3e8891b9ba7c53c (diff) | |
download | perl-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.c | 6 |
1 files changed, 3 insertions, 3 deletions
@@ -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) { |