aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/postmaster/postmaster.c33
-rw-r--r--src/port/pg_strong_random.c12
2 files changed, 31 insertions, 14 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index eedc617db4c..2d5a0ac7d3b 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -2520,11 +2520,13 @@ ClosePostmasterPorts(bool am_syslogger)
/*
* InitProcessGlobals -- set MyProcPid, MyStartTime[stamp], random seeds
*
- * Called early in every backend.
+ * Called early in the postmaster and every backend.
*/
void
InitProcessGlobals(void)
{
+ unsigned int rseed;
+
MyProcPid = getpid();
MyStartTimestamp = GetCurrentTimestamp();
MyStartTime = timestamptz_to_time_t(MyStartTimestamp);
@@ -2539,15 +2541,30 @@ InitProcessGlobals(void)
#endif
/*
- * Set a different seed for random() in every backend. Since PIDs and
- * timestamps tend to change more frequently in their least significant
- * bits, shift the timestamp left to allow a larger total number of seeds
- * in a given time period. Since that would leave only 20 bits of the
- * timestamp that cycle every ~1 second, also mix in some higher bits.
+ * Set a different seed for random() in every process. We want something
+ * unpredictable, so if possible, use high-quality random bits for the
+ * seed. Otherwise, fall back to a seed based on timestamp and PID.
+ *
+ * Note we can't use pg_backend_random here, since this is used in the
+ * postmaster, and even in a backend we might not be attached to shared
+ * memory yet.
*/
- srandom(((uint64) MyProcPid) ^
+#ifdef HAVE_STRONG_RANDOM
+ if (!pg_strong_random(&rseed, sizeof(rseed)))
+#endif
+ {
+ /*
+ * Since PIDs and timestamps tend to change more frequently in their
+ * least significant bits, shift the timestamp left to allow a larger
+ * total number of seeds in a given time period. Since that would
+ * leave only 20 bits of the timestamp that cycle every ~1 second,
+ * also mix in some higher bits.
+ */
+ rseed = ((uint64) MyProcPid) ^
((uint64) MyStartTimestamp << 12) ^
- ((uint64) MyStartTimestamp >> 20));
+ ((uint64) MyStartTimestamp >> 20);
+ }
+ srandom(rseed);
}
diff --git a/src/port/pg_strong_random.c b/src/port/pg_strong_random.c
index f9a06d66061..1408d3ad88e 100644
--- a/src/port/pg_strong_random.c
+++ b/src/port/pg_strong_random.c
@@ -6,6 +6,10 @@
* Our definition of "strong" is that it's suitable for generating random
* salts and query cancellation keys, during authentication.
*
+ * Note: this code is run quite early in postmaster and backend startup;
+ * therefore, even when built for backend, it cannot rely on backend
+ * infrastructure such as elog() or palloc().
+ *
* Copyright (c) 1996-2018, PostgreSQL Global Development Group
*
* IDENTIFICATION
@@ -14,11 +18,7 @@
*-------------------------------------------------------------------------
*/
-#ifndef FRONTEND
-#include "postgres.h"
-#else
-#include "postgres_fe.h"
-#endif
+#include "c.h"
#include <fcntl.h>
#include <unistd.h>
@@ -44,7 +44,7 @@ static HCRYPTPROV hProvider = 0;
* Read (random) bytes from a file.
*/
static bool
-random_from_file(char *filename, void *buf, size_t len)
+random_from_file(const char *filename, void *buf, size_t len)
{
int f;
char *p = buf;