From: Jarkko Hietaniemi Date: Fri, 11 Jul 2003 00:03:33 +0000 (+0000) Subject: Chicken out: the hash randomisation is not on by default. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=bed601927f5ca7f54b544d9e5ce1f77461311b68;p=p5sagit%2Fp5-mst-13.2.git Chicken out: the hash randomisation is not on by default. We switch over to the explicit mode: in other words, if the $ENV{PERL_HASH_SEED} is on, we randomise. Also, we randomise only if PL_hash_seed_set is FALSE (this means one can use PERL_HASH() before perl_run.) Also, since now PERL_HASH_SEED is okay even under -T, all should be fine. (Ha!) p4raw-id: //depot/perl@20135 --- diff --git a/embed.fnc b/embed.fnc index 19da53f..c138f76 100644 --- a/embed.fnc +++ b/embed.fnc @@ -839,6 +839,7 @@ p |void |vivify_ref |SV* sv|U32 to_what p |I32 |wait4pid |Pid_t pid|int* statusp|int flags p |U32 |parse_unicode_opts|char **popt p |U32 |seed +p |UV |get_seed p |void |report_evil_fh |GV *gv|IO *io|I32 op pd |void |report_uninit Afpd |void |warn |const char* pat|... diff --git a/embed.h b/embed.h index 2ba996b..add142d 100644 --- a/embed.h +++ b/embed.h @@ -1115,6 +1115,9 @@ #define seed Perl_seed #endif #ifdef PERL_CORE +#define get_seed Perl_get_seed +#endif +#ifdef PERL_CORE #define report_evil_fh Perl_report_evil_fh #endif #ifdef PERL_CORE @@ -3603,6 +3606,9 @@ #define seed() Perl_seed(aTHX) #endif #ifdef PERL_CORE +#define get_seed() Perl_get_seed(aTHX) +#endif +#ifdef PERL_CORE #define report_evil_fh(a,b,c) Perl_report_evil_fh(aTHX_ a,b,c) #endif #ifdef PERL_CORE diff --git a/embedvar.h b/embedvar.h index f990f9f..98d8b21 100644 --- a/embedvar.h +++ b/embedvar.h @@ -255,6 +255,7 @@ #define PL_glob_index (vTHX->Iglob_index) #define PL_globalstash (vTHX->Iglobalstash) #define PL_hash_seed (vTHX->Ihash_seed) +#define PL_hash_seed_set (vTHX->Ihash_seed_set) #define PL_he_arenaroot (vTHX->Ihe_arenaroot) #define PL_he_root (vTHX->Ihe_root) #define PL_hintgv (vTHX->Ihintgv) @@ -558,6 +559,7 @@ #define PL_Iglob_index PL_glob_index #define PL_Iglobalstash PL_globalstash #define PL_Ihash_seed PL_hash_seed +#define PL_Ihash_seed_set PL_hash_seed_set #define PL_Ihe_arenaroot PL_he_arenaroot #define PL_Ihe_root PL_he_root #define PL_Ihintgv PL_hintgv diff --git a/intrpvar.h b/intrpvar.h index 6d77cec..6a34ea4 100644 --- a/intrpvar.h +++ b/intrpvar.h @@ -525,6 +525,8 @@ PERLVARI(Ippid, IV, 0) PERLVARI(Ihash_seed, UV, 0) /* Hash initializer */ +PERLVARI(Ihash_seed_set, bool, FALSE) /* Hash initialized? */ + PERLVAR(IDBassertion, SV *) PERLVARI(Icv_has_eval, I32, 0) /* PL_compcv includes an entereval or similar */ diff --git a/perl.c b/perl.c index 1738489..32e0469 100644 --- a/perl.c +++ b/perl.c @@ -900,31 +900,18 @@ setuid perl scripts securely.\n"); #if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT) /* [perl #22371] Algorimic Complexity Attack on Perl 5.6.1, 5.8.0 * This MUST be done before any hash stores or fetches take place. */ + if (!PL_hash_seed_set) + PL_hash_seed = get_seed(); { - char *s = PerlEnv_getenv("PERL_HASH_SEED"); - if (s) - while (isSPACE(*s)) s++; - if (s && isDIGIT(*s)) - PL_hash_seed = (UV)Atoul(s); -#ifndef USE_HASH_SEED_EXPLICIT - else { - /* Compute a random seed */ - (void)seedDrand01((Rand_seed_t)seed()); - PL_srand_called = TRUE; - PL_hash_seed = (UV)(Drand01() * (NV)UV_MAX); -#if RANDBITS < (UVSIZE * 8) - /* Since there are not enough randbits to to reach all - * the bits of a UV, the low bits might need extra - * help. Sum in another random number that will - * fill in the low bits. */ - PL_hash_seed += - (UV)(Drand01() * (NV)((1 << ((UVSIZE * 8 - RANDBITS))) - 1)); -#endif /* RANDBITS < (UVSIZE * 8) */ - } -#endif /* #ifndef USE_HASH_SEED_EXPLICIT */ - if ((s = PerlEnv_getenv("PERL_HASH_SEED_DEBUG"))) - PerlIO_printf(Perl_debug_log, "HASH_SEED = %"UVuf"\n", - PL_hash_seed); + char *s = PerlEnv_getenv("PERL_HASH_SEED_DEBUG"); + + if (s) { + int i = atoi(s); + + if (i == 1) + PerlIO_printf(Perl_debug_log, "HASH_SEED = %"UVuf"\n", + PL_hash_seed); + } } #endif /* #if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT) */ diff --git a/perl.h b/perl.h index cb43a3d..24742c4 100644 --- a/perl.h +++ b/perl.h @@ -2258,7 +2258,7 @@ typedef struct crypt_data { /* straight from /usr/include/crypt.h */ /* [perl #22371] Algorimic Complexity Attack on Perl 5.6.1, 5.8.0 */ #if !defined(NO_HASH_SEED) && !defined(USE_HASH_SEED) && !defined(USE_HASH_SEED_EXPLICIT) -# define USE_HASH_SEED +# define USE_HASH_SEED_EXPLICIT #endif #include "regexp.h" diff --git a/perlapi.h b/perlapi.h index 123a7d5..524e84b 100644 --- a/perlapi.h +++ b/perlapi.h @@ -268,6 +268,8 @@ END_EXTERN_C #define PL_globalstash (*Perl_Iglobalstash_ptr(aTHX)) #undef PL_hash_seed #define PL_hash_seed (*Perl_Ihash_seed_ptr(aTHX)) +#undef PL_hash_seed_set +#define PL_hash_seed_set (*Perl_Ihash_seed_set_ptr(aTHX)) #undef PL_he_arenaroot #define PL_he_arenaroot (*Perl_Ihe_arenaroot_ptr(aTHX)) #undef PL_he_root diff --git a/pod/perlrun.pod b/pod/perlrun.pod index 26d0bc4..730c75d 100644 --- a/pod/perlrun.pod +++ b/pod/perlrun.pod @@ -1127,8 +1127,8 @@ See L for more information. =item PERL_HASH_SEED_DEBUG -(Since Perl 5.8.1.) Set to (anything) to display (to STDERR) -the value of the hash seed at the beginning of execution. +(Since Perl 5.8.1.) Set to "1" to display (to STDERR) the value of +the hash seed at the beginning of execution. =item PERL_ROOT (specific to the VMS port) diff --git a/proto.h b/proto.h index bb91615..57f7027 100644 --- a/proto.h +++ b/proto.h @@ -799,6 +799,7 @@ PERL_CALLCONV void Perl_vivify_ref(pTHX_ SV* sv, U32 to_what); PERL_CALLCONV I32 Perl_wait4pid(pTHX_ Pid_t pid, int* statusp, int flags); PERL_CALLCONV U32 Perl_parse_unicode_opts(pTHX_ char **popt); PERL_CALLCONV U32 Perl_seed(pTHX); +PERL_CALLCONV UV Perl_get_seed(pTHX); PERL_CALLCONV void Perl_report_evil_fh(pTHX_ GV *gv, IO *io, I32 op); PERL_CALLCONV void Perl_report_uninit(pTHX); PERL_CALLCONV void Perl_warn(pTHX_ const char* pat, ...) diff --git a/util.c b/util.c index 80af155..4f53a91 100644 --- a/util.c +++ b/util.c @@ -4377,3 +4377,35 @@ Perl_seed(pTHX) return u; } +UV +Perl_get_seed(void) +{ + char *s = PerlEnv_getenv("PERL_HASH_SEED"); + UV myseed = 0; + + if (s) + while (isSPACE(*s)) s++; + if (s && isDIGIT(*s)) + myseed = (UV)Atoul(s); + else +#ifdef USE_HASH_SEED_EXPLICIT + if (s) +#endif + { + /* Compute a random seed */ + (void)seedDrand01((Rand_seed_t)seed()); + PL_srand_called = TRUE; + myseed = (UV)(Drand01() * (NV)UV_MAX); +#if RANDBITS < (UVSIZE * 8) + /* Since there are not enough randbits to to reach all + * the bits of a UV, the low bits might need extra + * help. Sum in another random number that will + * fill in the low bits. */ + myseed += + (UV)(Drand01() * (NV)((1 << ((UVSIZE * 8 - RANDBITS))) - 1)); +#endif /* RANDBITS < (UVSIZE * 8) */ + } + PL_hash_seed_set = TRUE; + + return myseed; +}