diff options
author | Yves Orton <demerphq@gmail.com> | 2013-05-05 16:33:43 +0200 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2013-05-07 09:33:42 +0200 |
commit | 6a5b4183fb7901110d40b26a7e60b0950cc9465d (patch) | |
tree | 03097efff3b551cc07b262968b9a238f7cac6f6f /hv.h | |
parent | 64c33badc975262c1617c4756a5a7868443e14e8 (diff) | |
download | perl-6a5b4183fb7901110d40b26a7e60b0950cc9465d.tar.gz |
Make it possible to disable and control hash key traversal randomization
Adds support for PERL_PERTURB_KEYS environment variable, which in turn allows one to control
the level of randomization applied to keys() and friends.
When PERL_PERTURB_KEYS is 0 we will not randomize key order at all. The
chance that keys() changes due to an insert will be the same as in
previous perls, basically only when the bucket size is changed.
When PERL_PERTURB_KEYS is 1 we will randomize keys in a non repeatedable
way. The chance that keys() changes due to an insert will be very high.
This is the most secure and default mode.
When PERL_PERTURB_KEYS is 2 we will randomize keys in a repeatedable way.
Repititive runs of the same program should produce the same output every
time. The chance that keys changes due to an insert will be very high.
This patch also makes PERL_HASH_SEED imply a non-default
PERL_PERTURB_KEYS setting. Setting PERL_HASH_SEED=0 (exactly one 0) implies
PERL_PERTURB_KEYS=0 (hash key randomization disabled), settng PERL_HASH_SEED
to any other value, implies PERL_PERTURB_KEYS=2 (deterministic/repeatable
hash key randomization). Specifying PERL_PERTURB_KEYS explicitly to a
different level overrides this behavior.
Includes changes to allow one to compile out various aspects of the
patch. One can compile such that PERL_PERTURB_KEYS is not respected, or
can compile without hash key traversal randomization at all. Note that
support for these modes is incomplete, and currently a few tests will
fail.
Also includes a new subroutine in Hash::Util::hash_traversal_mask()
which can be used to ensure a given hash produces a predictable key
order (assuming the same hash seed is in effect). This sub acts as a
getter and a setter.
NOTE - this patch lacks tests, but I lack tuits to get them done quickly,
so I am pushing this with the hope that others can add them afterwards.
Diffstat (limited to 'hv.h')
-rw-r--r-- | hv.h | 18 |
1 files changed, 18 insertions, 0 deletions
@@ -8,6 +8,22 @@ * */ +/* These control hash traversal randomization and the environment variable PERL_PERTURB_KEYS. + * Currently disabling this functionality will break a few tests, but should otherwise work fine. + * See perlrun for more details. */ +#define PERL_HASH_RANDOMIZE_KEYS 1 +#define USE_PERL_PERTURB_KEYS 1 + + +#ifdef PERL_HASH_RANDOMIZE_KEYS +# if defined(DEBUGGING) || defined(USE_PERL_PERTURB_KEYS) +# define PL_HASH_RAND_BITS_ENABLED PL_hash_rand_bits_enabled +# endif +# define PERL_HASH_ITER_BUCKET(iter) (((iter)->xhv_riter) ^ ((iter)->xhv_rand)) +#else +# define PERL_HASH_ITER_BUCKET(iter) ((iter)->xhv_riter) +#endif + /* entry in hash value chain */ struct he { /* Keep hent_next first in this structure, because sv_free_arenas take @@ -92,9 +108,11 @@ struct xpvhv_aux { I32 xhv_name_count; struct mro_meta *xhv_mro_meta; HV * xhv_super; /* SUPER method cache */ +#ifdef PERL_HASH_RANDOMIZE_KEYS U32 xhv_rand; /* random value for hash traversal */ U32 xhv_last_rand; /* last random value for hash traversal, used to detect each() after insert for warnings */ +#endif }; /* hash structure: */ |