stas 2003/07/30 05:18:06
Modified: src/modules/perl mod_perl.c modperl_apache_includes.h . Changes Log: perl 5.8.1 randomizes the hash seed, because we precalculate the hash values of mgv elements the hash seed has to be the same across all perl interpreters. So mod_perl now intercepts cases where perl would have randomize it, do the seed randomization by itself and tell perl to use that value. Revision Changes Path 1.174 +71 -0 modperl-2.0/src/modules/perl/mod_perl.c Index: mod_perl.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.c,v retrieving revision 1.173 retrieving revision 1.174 diff -u -r1.173 -r1.174 --- mod_perl.c 7 Jul 2003 03:06:14 -0000 1.173 +++ mod_perl.c 30 Jul 2003 12:18:06 -0000 1.174 @@ -9,6 +9,74 @@ #define MP_IS_STARTING (MP_init_status == 1 ? 1 : 0) #define MP_IS_RUNNING (MP_init_status == 2 ? 1 : 0) +#if !(PERL_REVISION == 5 && ( PERL_VERSION < 8 || \ + (PERL_VERSION == 8 && PERL_SUBVERSION == 0))) && \ + (defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT)) +#define MP_NEED_HASH_SEED_FIXUP +#endif + + +#ifdef MP_NEED_HASH_SEED_FIXUP +static UV MP_init_hash_seed = 0; +static bool MP_init_hash_seed_set = FALSE; +#endif + +/* see modperl_hash_seed_set() */ +static void modperl_hash_seed_init(apr_pool_t *p) +{ +#ifdef MP_NEED_HASH_SEED_FIXUP + char *s; + + /* check if there is a specific hash seed passed via the env var + * and if that's the case -- use it */ + apr_status_t rv = apr_env_get(&s, "PERL_HASH_SEED", p); + if (rv != APR_ENOTIMPL) { + if (s) { + while (isSPACE(*s)) s++; + } + if (s && isDIGIT(*s)) { + MP_init_hash_seed = (UV)Atol(s); // XXX: Atoul()? + MP_init_hash_seed_set = TRUE; + } + } + + /* calculate our own random hash seed */ + if (!MP_init_hash_seed_set) { + apr_uuid_t *uuid = (apr_uuid_t *)safemalloc(sizeof(apr_uuid_t)); + char buf[APR_UUID_FORMATTED_LENGTH + 1]; + int i; + + apr_initialize(); + apr_uuid_get(uuid); + apr_uuid_format(buf, uuid); + /* fprintf(stderr, "UUID: %s\n", buf); */ + + /* XXX: need a better alg to convert uuid string into a seed */ + for (i=0; buf[i]; i++){ + MP_init_hash_seed += (UV)(i+1)*(buf[i]+MP_init_hash_seed); + } + + MP_init_hash_seed_set = TRUE; + } + + /* fprintf(stderr, "GOT SEED: %ld\n", MP_init_hash_seed); */ +#endif +} + +/* before 5.8.1, perl was using HASH_SEED=0, starting from 5.8.1 + * it randomizes if perl was compiled with ccflags -DUSE_HASH_SEED + * or -DUSE_HASH_SEED_EXPLICIT, in which case we need to tell perl + * to use the same seed everywhere */ +static void modperl_hash_seed_set(pTHX) +{ +#ifdef MP_NEED_HASH_SEED_FIXUP + if (MP_init_hash_seed_set) { + PL_hash_seed_set = TRUE; + PL_hash_seed = MP_init_hash_seed; + } +#endif +} + #ifndef USE_ITHREADS static apr_status_t modperl_shutdown(void *data) { @@ -164,6 +232,8 @@ perl_construct(perl); + modperl_hash_seed_set(aTHX); + PL_perl_destruct_level = 2; MP_boot_data_set(p, s); @@ -510,6 +580,7 @@ /* XXX: htf can we have PerlPreConfigHandler * without first configuring mod_perl ? */ + modperl_hash_seed_init(p); return OK; } 1.24 +3 -0 modperl-2.0/src/modules/perl/modperl_apache_includes.h Index: modperl_apache_includes.h =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_apache_includes.h,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- modperl_apache_includes.h 24 Apr 2003 01:51:37 -0000 1.23 +++ modperl_apache_includes.h 30 Jul 2003 12:18:06 -0000 1.24 @@ -34,6 +34,9 @@ #include "apr_buckets.h" #include "apr_time.h" #include "apr_network_io.h" +#include "apr_general.h" +#include "apr_uuid.h" +#include "apr_env.h" #include "util_filter.h" 1.201 +6 -0 modperl-2.0/Changes Index: Changes =================================================================== RCS file: /home/cvs/modperl-2.0/Changes,v retrieving revision 1.200 retrieving revision 1.201 diff -u -r1.200 -r1.201 --- Changes 29 Jul 2003 09:28:19 -0000 1.200 +++ Changes 30 Jul 2003 12:18:06 -0000 1.201 @@ -12,6 +12,12 @@ =item 1.99_10-dev +perl 5.8.1 randomizes the hash seed, because we precalculate the hash +values of mgv elements the hash seed has to be the same across all +perl interpreters. So mod_perl now intercepts cases where perl would +have randomize it, do the seed randomization by itself and tell perl +to use that value. [Stas] + fix APR::PerlIO layer to pop itself if open() has failed. [Stas] move the definition of DEFINE='-DMP_HAVE_APR_LIBS' to the top level