summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2013-03-17 20:48:45 +0100
committerYves Orton <demerphq@gmail.com>2013-03-19 00:23:12 +0100
commitd5fc06cbb416442b7c14833a0e107aa24005a47b (patch)
tree64161b3e83937dee38572814f19a34c110cdaeae /hv.c
parent3078e109184e83a0c0e99d9eea771d67b90f1e72 (diff)
downloadperl-d5fc06cbb416442b7c14833a0e107aa24005a47b.tar.gz
ensure that inserting into a hash causes its hash iteration order to change
This serves two functions, it makes it harder for an attacker to learn useful information by viewing the output of keys(), and it makes "insert during traversal" errors much easier to spot, as they will almost always produce degenerate behavior.
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/hv.c b/hv.c
index 3de86d1e89..5fc02963da 100644
--- a/hv.c
+++ b/hv.c
@@ -789,8 +789,11 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
/* This logic semi-randomizes the insert order in a bucket.
* Either we insert into the top, or the slot below the top,
- * making it harder to see if there is a collision.
+ * making it harder to see if there is a collision. We also
+ * reset the iterator randomizer if there is one.
*/
+ if (SvOOK(hv))
+ HvAUX(hv)->xhv_rand= (U32)PL_hash_rand_bits;
PL_hash_rand_bits += (PTRV)entry ^ hash; /* we don't bother to use ptr_hash here */
PL_hash_rand_bits= ROTL_UV(PL_hash_rand_bits,1);
if ( !*oentry || (PL_hash_rand_bits & 1) ) {