pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Tom Lane <tgl@sss.pgh.pa.us>
To: Thomas Munro <thomas.munro@enterprisedb.com>
Cc: Heikki Linnakangas <hlinnaka@iki.fi>
Cc: Peter Geoghegan <pg@bowt.ie>
Cc: Michael Paquier <michael@paquier.xyz>
Cc: Alvaro Herrera <alvherre@2ndquadrant.com>
Cc: Adrien Nayrat <adrien.nayrat@anayrat.info>
Cc: Dmitry Dolgov <9erthalion6@gmail.com>
Cc: Tomas Vondra <tomas.vondra@2ndquadrant.com>
Cc: Vik Fearing <vik.fearing@2ndquadrant.com>
Cc: Robert Haas <robertmhaas@gmail.com>
Cc: David Rowley <david.rowley@2ndquadrant.com>
Cc: Pg Hackers <pgsql-hackers@postgresql.org>
Subject: Re: random() (was Re: New GUC to sample log queries)
Date: Fri, 28 Dec 2018 18:15:05 -0500
Message-ID: <10913.1546038905@sss.pgh.pa.us> (raw)
In-Reply-To: <9703.1545939393@sss.pgh.pa.us>
References: <20181129214850.kiq6mvofsgplqjdr@alvherre.pgsql>
	<3859.1545849900@sss.pgh.pa.us>
	<20181227013458.GF2106@paquier.xyz>
	<32696.1545875185@sss.pgh.pa.us>
	<CAH2-Wz=xJiy+BgU7M49L6EHSkMbJWbzbprge=AqyOC8aDXRj8A@mail.gmail.com>
	<2820.1545878340@sss.pgh.pa.us>
	<CAH2-WznuXsWmjnvbt=odKMVxpj1zutgzRb7s6Vu3VPXCjejS5g@mail.gmail.com>
	<CAEepm=1tJB2=w_GdXHRLkWQcCnFWGdmNiEdd5rupShKT=DwWyQ@mail.gmail.com>
	<9703.1545939393@sss.pgh.pa.us>

I wrote:
> Thomas Munro <thomas.munro@enterprisedb.com> writes:
>> +1, but I wonder if just separating them is enough.  Is our seeding
>> algorithm good enough for this new purpose?  The initial seed is 100%
>> predictable to a logged in user (it's made from the backend PID and
>> backend start time, which we tell you), and not even that hard to
>> guess from the outside, so I think Coverity's warning is an
>> understatement in this case.  Even if we separate the PRNG state used
>> for internal stuff so that users can't clobber its seed from SQL,
>> wouldn't it be possible to predict which statements will survive the
>> log sampling filter given easily available information and a good
>> guess at how many times random() (or whatever similar thing) has been
>> called so far?

> Yeah, that's a good point.  Maybe we should upgrade the per-process
> seed initialization to make it less predictable.  I could see expending
> a call of the strong RNG to contribute some more noise to the seeds
> selected in InitProcessGlobals().

Here's a simple patch to do so.

Looking at this, I seem to remember that we considered doing exactly this
awhile ago, but refrained because there was concern about depleting the
system's reserve of entropy if we have a high backend spawn rate, and it
didn't seem like there was a security reason to insist on unpredictable
random() results.  However, the log-sampling patch destroys the latter
argument.  As for the former argument, I'm not sure how big a deal that
really is.  Presumably, the act of spawning a backend would itself
contribute some more entropy to the pool (particularly if a network
connection is involved), so the depletion problem might be fictitious
in the first place.  Also, a few references I consulted, such as the
Linux urandom(4) man page, suggest that even in a depleted-entropy
state the results of reading /dev/urandom should be random enough
for all but the very strictest security requirements.

Thoughts?

			regards, tom lane

Attachments:

  [text/x-diff] make-random-seed-more-random-1.patch (2.5K, ../10913.1546038905@sss.pgh.pa.us/2-make-random-seed-more-random-1.patch)
  download | inline diff:
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index eedc617..2d5a0ac 100644
*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
*************** ClosePostmasterPorts(bool am_syslogger)
*** 2520,2530 ****
  /*
   * InitProcessGlobals -- set MyProcPid, MyStartTime[stamp], random seeds
   *
!  * Called early in every backend.
   */
  void
  InitProcessGlobals(void)
  {
  	MyProcPid = getpid();
  	MyStartTimestamp = GetCurrentTimestamp();
  	MyStartTime = timestamptz_to_time_t(MyStartTimestamp);
--- 2520,2532 ----
  /*
   * InitProcessGlobals -- set MyProcPid, MyStartTime[stamp], random seeds
   *
!  * Called early in the postmaster and every backend.
   */
  void
  InitProcessGlobals(void)
  {
+ 	unsigned int rseed;
+ 
  	MyProcPid = getpid();
  	MyStartTimestamp = GetCurrentTimestamp();
  	MyStartTime = timestamptz_to_time_t(MyStartTimestamp);
*************** InitProcessGlobals(void)
*** 2539,2553 ****
  #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.
  	 */
! 	srandom(((uint64) MyProcPid) ^
  			((uint64) MyStartTimestamp << 12) ^
! 			((uint64) MyStartTimestamp >> 20));
  }
  
  
--- 2541,2570 ----
  #endif
  
  	/*
! 	 * 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.
  	 */
! #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);
! 	}
! 	srandom(rseed);
  }
  
  =

view thread (33+ messages)  latest in thread

Message-ID: <10913.1546038905@sss.pgh.pa.us>
Permalink:  ../10913.1546038905@sss.pgh.pa.us/
Also on:    postgresql.org/message-id/10913.1546038905@sss.pgh.pa.us

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: tgl@sss.pgh.pa.us, thomas.munro@enterprisedb.com, hlinnaka@iki.fi, pg@bowt.ie, michael@paquier.xyz, alvherre@2ndquadrant.com, adrien.nayrat@anayrat.info, 9erthalion6@gmail.com, tomas.vondra@2ndquadrant.com, vik.fearing@2ndquadrant.com, robertmhaas@gmail.com, david.rowley@2ndquadrant.com
  Subject: Re: random() (was Re: New GUC to sample log queries)
  In-Reply-To: <10913.1546038905@sss.pgh.pa.us>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox