Skip to content

Commit ecdd0c8

Browse files
committed
(perl #127663) create a separate random souce for internal use
and use it to initialize hash randomization and to innoculate against quadratic behaviour in pp_sort
1 parent 5aa240e commit ecdd0c8

File tree

6 files changed

+19
-4
lines changed

6 files changed

+19
-4
lines changed

embedvar.h

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@
173173
#define PL_incgv (vTHX->Iincgv)
174174
#define PL_initav (vTHX->Iinitav)
175175
#define PL_inplace (vTHX->Iinplace)
176+
#define PL_internal_random_state (vTHX->Iinternal_random_state)
176177
#define PL_isarev (vTHX->Iisarev)
177178
#define PL_known_layers (vTHX->Iknown_layers)
178179
#define PL_last_in_gv (vTHX->Ilast_in_gv)

intrpvar.h

+8
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,14 @@ PERLVAR(I, random_state, PL_RANDOM_STATE_TYPE)
810810

811811
PERLVARI(I, dump_re_max_len, STRLEN, 0)
812812

813+
/* For internal uses of randomness, this ensures the sequence of
814+
* random numbers returned by rand() isn't modified by perl's internal
815+
* use of randomness.
816+
* This is important if the user has called srand() with a seed.
817+
*/
818+
819+
PERLVAR(I, internal_random_state, PL_RANDOM_STATE_TYPE)
820+
813821
/* If you are adding a U8 or U16, check to see if there are 'Space' comments
814822
* above on where there are gaps which currently will be structure padding. */
815823

perl.c

+2
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ perl_construct(pTHXx)
261261

262262
init_constants();
263263

264+
Perl_drand48_init_r(&PL_internal_random_state, seed());
265+
264266
SvREADONLY_on(&PL_sv_placeholder);
265267
SvREFCNT(&PL_sv_placeholder) = SvREFCNT_IMMORTAL;
266268

pp_sort.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ S_qsortsvu(pTHX_ SV ** array, size_t num_elts, SVCOMPARE_t compare)
787787
size_t n;
788788
SV ** const q = array;
789789
for (n = num_elts; n > 1; ) {
790-
const size_t j = (size_t)(n-- * Drand01());
790+
const size_t j = (size_t)(n-- * Perl_internal_drand48());
791791
temp = q[j];
792792
q[j] = q[n];
793793
q[n] = temp;

util.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -4757,10 +4757,8 @@ Perl_get_hash_seed(pTHX_ unsigned char * const seed_buffer)
47574757
else
47584758
#endif
47594759
{
4760-
(void)seedDrand01((Rand_seed_t)seed());
4761-
47624760
for( i = 0; i < PERL_HASH_SEED_BYTES; i++ ) {
4763-
seed_buffer[i] = (unsigned char)(Drand01() * (U8_MAX+1));
4761+
seed_buffer[i] = (unsigned char)(Perl_internal_drand48() * (U8_MAX+1));
47644762
}
47654763
}
47664764
#ifdef USE_PERL_PERTURB_KEYS

util.h

+6
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ typedef struct PERL_DRAND48_T perl_drand48_t;
8585
#define Perl_drand48_init(seed) (Perl_drand48_init_r(&PL_random_state, (seed)))
8686
#define Perl_drand48() (Perl_drand48_r(&PL_random_state))
8787

88+
#ifdef PERL_CORE
89+
/* uses a different source of randomness to avoid interfering with the results
90+
* of rand() */
91+
#define Perl_internal_drand48() (Perl_drand48_r(&PL_internal_random_state))
92+
#endif
93+
8894
#ifdef USE_C_BACKTRACE
8995

9096
typedef struct {

0 commit comments

Comments
 (0)