File nss-CC-drbg_fork_reseeds.patch of Package mozilla-nss.972
# HG changeset patch
# Parent 858d4927422479cf13bdd90a2557190d09d2c2d6
Reseed PRNG before giving out any random data after a fork()
Also see bsc#918112
diff --git a/lib/freebl/drbg.c b/lib/freebl/drbg.c
--- a/lib/freebl/drbg.c
+++ b/lib/freebl/drbg.c
@@ -15,16 +15,21 @@
#include "blapii.h"
#include "nssilock.h"
#include "secitem.h"
#include "sha_fast.h"
#include "sha256.h"
#include "secrng.h" /* for RNG_SystemRNG() */
#include "secmpi.h"
+#ifdef XP_UNIX
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
/* PRNG_SEEDLEN defined in NIST SP 800-90 section 10.1
* for SHA-1, SHA-224, and SHA-256 it's 440 bits.
* for SHA-384 and SHA-512 it's 888 bits */
#define PRNG_SEEDLEN (440/PR_BITS_PER_BYTE)
static const PRInt64 PRNG_MAX_ADDITIONAL_BYTES = LL_INIT(0x1, 0x0);
/* 2^35 bits or 2^32 bytes */
#define PRNG_MAX_REQUEST_SIZE 0x10000 /* 2^19 bits or 2^16 bytes */
#define PRNG_ADDITONAL_DATA_CACHE_SIZE (8*1024) /* must be less than
@@ -101,16 +106,38 @@ struct RNGContextStr {
* first generated random block, which is used
* solely for continuous testing */
};
typedef struct RNGContextStr RNGContext;
static RNGContext *globalrng = NULL;
static RNGContext theGlobalRng;
+#ifdef XP_UNIX
+/* require PRNG reseed if the process has been recently forked */
+static pid_t myPid = 0;
+
+static PRBool
+prng_fork_reseed_needed(void)
+{
+ pid_t curPid;
+ PRBool retval = PR_FALSE;
+
+ if (myPid) {
+ curPid = getpid();
+ if (myPid != curPid) {
+ myPid = curPid;
+ retval = PR_TRUE;
+ }
+ } else {
+ myPid = getpid();
+ }
+ return retval;
+}
+#endif
/*
* The next several functions are derived from the NIST SP 800-90
* spec. In these functions, an attempt was made to use names consistent
* with the names in the spec, even if they differ from normal NSS usage.
*/
/*
@@ -689,16 +716,23 @@ prng_GenerateGlobalRandomBytes(RNGContex
/*
** Generate some random bytes, using the global random number generator
** object.
*/
SECStatus
RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
{
+#ifdef XP_UNIX
+ SECStatus rv;
+ if (prng_fork_reseed_needed()) {
+ if (rv = prng_reseed(globalrng, NULL, 0, NULL, 0))
+ return rv;
+ }
+#endif
return prng_GenerateGlobalRandomBytes(globalrng, dest, len);
}
void
RNG_RNGShutdown(void)
{
/* check for a valid global RNG context */
PORT_Assert(globalrng != NULL);