summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2016-12-08 09:38:55 +1100
committerTony Cook <tony@develop-help.com>2017-09-11 10:59:43 +1000
commitd62950713a9b1969a52015f065537f4a2cc224f3 (patch)
treee9808532fdccef3815b692898882118256d20738
parent929344c06d753c7727ddb290d2b5b2dd62462cc5 (diff)
downloadperl-d62950713a9b1969a52015f065537f4a2cc224f3.tar.gz
(perl #127663) provide limited control for the internal drand48()
perl can be built without PERL_INTERNAL_RAND_SEED support to reduce it's attack surface.
-rw-r--r--INSTALL6
-rw-r--r--perl.c29
-rw-r--r--pod/perlrun.pod12
3 files changed, 47 insertions, 0 deletions
diff --git a/INSTALL b/INSTALL
index 5a88ded723..fbce4f5469 100644
--- a/INSTALL
+++ b/INSTALL
@@ -2721,6 +2721,12 @@ F<mathoms.c> will not be compiled in. Those functions are no longer used
by perl itself; for source compatibility reasons, though, they weren't
completely removed.
+=head2 C<-DNO_PERL_INTERNAL_RAND_SEED>
+X<PERL_INTERNAL_RAND_SEED>
+
+If you configure perl with C<-Accflags=-DNO_PERL_INTERNAL_RAND_SEED>,
+perl will ignore the C<PERL_INTERNAL_RAND_SEED> enviroment variable.
+
=head1 DOCUMENTATION
Read the manual entries before running perl. The main documentation
diff --git a/perl.c b/perl.c
index 7db5f158d5..fd100cc64a 100644
--- a/perl.c
+++ b/perl.c
@@ -261,7 +261,21 @@ perl_construct(pTHXx)
init_constants();
+#ifdef NO_PERL_INTERNAL_RAND_SEED
Perl_drand48_init_r(&PL_internal_random_state, seed());
+#else
+ {
+ UV seed;
+ const char *env_pv;
+ if (PerlProc_getuid() != PerlProc_geteuid() ||
+ PerlProc_getgid() != PerlProc_getegid() ||
+ !(env_pv = PerlEnv_getenv("PERL_INTERNAL_RAND_SEED")) ||
+ grok_number(env_pv, strlen(env_pv), &seed) != IS_NUMBER_IN_UV) {
+ seed = seed();
+ }
+ Perl_drand48_init_r(&PL_internal_random_state, (U32)seed);
+ }
+#endif
SvREADONLY_on(&PL_sv_placeholder);
SvREFCNT(&PL_sv_placeholder) = SvREFCNT_IMMORTAL;
@@ -2204,6 +2218,21 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
}
}
+#ifndef NO_PERL_INTERNAL_RAND_SEED
+ /* If we're not set[ug]id, we might have honored
+ PERL_INTERNAL_RAND_SEED in perl_construct().
+ At this point command-line options have been parsed, so if
+ we're now tainting and not set[ug]id re-seed.
+ This could possibly be wasteful if PERL_INTERNAL_RAND_SEED is invalid,
+ but avoids duplicating the logic from perl_construct().
+ */
+ if (PL_tainting &&
+ PerlProc_getuid() == PerlProc_geteuid() &&
+ PerlProc_getgid() == PerlProc_getegid()) {
+ Perl_drand48_init_r(&PL_internal_random_state, seed());
+ }
+#endif
+
/* Set $^X early so that it can be used for relocatable paths in @INC */
/* and for SITELIB_EXP in USE_SITECUSTOMIZE */
assert (!TAINT_get);
diff --git a/pod/perlrun.pod b/pod/perlrun.pod
index f32c8edc98..b5e4c06517 100644
--- a/pod/perlrun.pod
+++ b/pod/perlrun.pod
@@ -1392,6 +1392,18 @@ X<SYS$LOGIN>
Used if chdir has no argument and HOME and LOGDIR are not set.
+=item PERL_INTERNAL_RAND_SEED
+X<PERL_INTERNAL_RAND_SEED>
+
+Set to a non-negative integer to seed the random number generator used
+internally by perl for a variety of purposes.
+
+Ignored if perl is run setuid or setgid. Used only for some limited
+startup randomization (hash keys) if C<-T> or C<-t> perl is started
+with tainting enabled.
+
+Perl may be built to ignore this variable.
+
=back
Perl also has environment variables that control how Perl handles data