Initialize random() in bootstrap/stand-alone postgres and in initdb.
authorNoah Misch
Mon, 24 Sep 2018 05:56:39 +0000 (22:56 -0700)
committerNoah Misch
Mon, 24 Sep 2018 05:56:57 +0000 (22:56 -0700)
This removes a difference between the standard IsUnderPostmaster
execution environment and that of --boot and --single.  In a stand-alone
backend, "SELECT random()" always started at the same seed.

On a system capable of using posix shared memory, initdb could still
conclude "selecting dynamic shared memory implementation ... sysv".
Crashed --boot or --single postgres processes orphaned shared memory
objects having names that collided with the not-actually-random names
that initdb probed.  The sysv fallback appeared after ten crashes of
--boot or --single postgres.  Since --boot and --single are rare in
production use, systems used for PostgreSQL development are the
principal candidate to notice this symptom.

Back-patch to 9.3 (all supported versions).  PostgreSQL 9.4 introduced
dynamic shared memory, but 9.3 does share the "SELECT random()" problem.

Reviewed by Tom Lane and Kyotaro HORIGUCHI.

Discussion: https://postgr.es/m/20180915221546[email protected]

src/backend/bootstrap/bootstrap.c
src/backend/tcop/postgres.c
src/bin/initdb/initdb.c

index 0e14b9272b5bdd0b8e5509a8e020236e060c34f1..0943a59d660121e6006d62f0f0b0ec562f5edd7d 100644 (file)
@@ -197,6 +197,14 @@ AuxiliaryProcessMain(int argc, char *argv[])
 
    MyStartTime = time(NULL);
 
+   /*
+    * Initialize random() for the first time, like PostmasterMain() would.
+    * In a regular IsUnderPostmaster backend, BackendRun() computes a
+    * high-entropy seed before any user query.  Fewer distinct initial seeds
+    * can occur here.
+    */
+   srandom((unsigned int) (MyProcPid ^ MyStartTime));
+
    /* Compute paths, if we didn't inherit them from postmaster */
    if (my_exec_path[0] == '\0')
    {
index 5903b228905e185d5a95c55fb18416b5ecbb5941..98180ed52abee2a59daec688794dbff015594295 100644 (file)
@@ -3611,6 +3611,14 @@ PostgresMain(int argc, char *argv[],
        MyProcPid = getpid();
 
        MyStartTime = time(NULL);
+
+       /*
+        * Initialize random() for the first time, like PostmasterMain()
+        * would.  In a regular IsUnderPostmaster backend, BackendRun()
+        * computes a high-entropy seed before any user query.  Fewer distinct
+        * initial seeds can occur here.
+        */
+       srandom((unsigned int) (MyProcPid ^ MyStartTime));
    }
 
    SetProcessingMode(InitProcessing);
index 6de22ba65e148f44a7153974d4ccd1a420df036f..fb16897adf0965ad2af83a218a3ef0cc3e11581c 100644 (file)
@@ -1055,6 +1055,9 @@ choose_dsm_implementation(void)
 #ifdef HAVE_SHM_OPEN
    int         ntries = 10;
 
+   /* Initialize random(); this function is its only user in this program. */
+   srandom((unsigned int) (getpid() ^ time(NULL)));
+
    while (ntries > 0)
    {
        uint32      handle;