public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/nss] rawhide: Reseed the freebl DRBG after fork()
@ 2026-07-29 17:43 Rostislav Krasny
0 siblings, 0 replies; only message in thread
From: Rostislav Krasny @ 2026-07-29 17:43 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/nss
Branch : rawhide
Commit : c2bfe9182ac781ae9e5f459a20ca72be43e8c168
Author : Rostislav Krasny <rostiprodev@gmail.com>
Date : 2026-07-29T19:42:48+02:00
Stats : +106/-0 in 2 file(s)
URL : https://src.fedoraproject.org/rpms/nss/c/c2bfe9182ac781ae9e5f459a20ca72be43e8c168?branch=rawhide
Log:
Reseed the freebl DRBG after fork()
fork() gives the child a verbatim copy of theGlobalRng together with the
PR_CallOnce flags that mark it instantiated, so RNG_RNGInit() in the child
is a no-op and the child replays the parent's output stream. Register a
pthread_atfork child handler that discards the inherited state, forcing a
clean reinstantiate from system entropy at the next RNG use.
Also add the NULL check RNG_RandomUpdate() was missing. Its sibling
prng_GenerateGlobalRandomBytes() already has one, and without it the
PR_Lock() below dereferences NULL.
Reported against Firefox's Linux fork server, where content processes
forked from a common ancestor generated identical UUIDs (mozbz#2056509),
but the defect affects any NSS consumer that forks without exec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---
diff --git a/nss-3.125-drbg-reseed-after-fork.patch b/nss-3.125-drbg-reseed-after-fork.patch
new file mode 100644
index 0000000..9f73f89
--- /dev/null
+++ b/nss-3.125-drbg-reseed-after-fork.patch
@@ -0,0 +1,98 @@
+--- a/lib/freebl/drbg.c 2026-07-25 00:09:40.452942615 +0300
++++ b/lib/freebl/drbg.c 2026-07-25 01:11:29.163041842 +0300
+@@ -20,6 +20,10 @@
+ #include "secrng.h" /* for RNG_SystemRNG() */
+ #include "secmpi.h"
+
++#ifdef XP_UNIX
++#include <pthread.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 */
+@@ -471,6 +475,45 @@
+ */
+ static const PRCallOnceType pristineCallOnce;
+ static PRCallOnceType coRNGInit;
++
++#ifdef XP_UNIX
++static PRCallOnceType coRNGInitAtFork;
++
++/* fork() gives the child a verbatim copy of the DRBG state, including the
++ * PR_CallOnce flags marking it instantiated, so without this the child
++ * replays the parent's output stream.
++ *
++ * Keep async-signal-safe -- no allocation, locks or I/O -- for callers that
++ * fork from a multithreaded process; the reinstantiate is deferred to the
++ * next RNG use. Only fork mechanisms that run atfork handlers are covered.
++ * Never run this after vfork(2): that child shares the parent's address
++ * space, so the zeroing below would destroy the live context. */
++static void
++rng_atfork_child(void)
++{
++ /* Zero the storage, not *globalrng: after RNG_RNGShutdown() the pointer
++ * is NULL while the context still holds C and V that prng_freeRNGContext
++ * deliberately preserved. Discarding them forces a clean reinstantiate
++ * rather than a reseed over inherited state, and clears the stale lock
++ * pointer so rng_init() builds a fresh one. The inherited PRLock is
++ * leaked on purpose: a thread that did not survive the fork may have held
++ * it, so destroying it would be undefined. */
++ PORT_SafeZero(&theGlobalRng, sizeof(theGlobalRng));
++ globalrng = NULL;
++ /* Reset both: the first otherwise suppresses rng_init() entirely, the
++ * second leaves previousEntropyHash zeroed while claiming it was primed. */
++ coRNGInit = pristineCallOnce;
++ coRNGInitEntropy = pristineCallOnce;
++}
++
++static PRStatus
++rng_registerAtFork(void)
++{
++ pthread_atfork(NULL, NULL, rng_atfork_child);
++ return PR_SUCCESS;
++}
++#endif
++
+ static PRStatus
+ rng_init(void)
+ {
+@@ -478,6 +521,12 @@
+ SECStatus rv = SECSuccess;
+
+ if (globalrng == NULL) {
++#ifdef XP_UNIX
++ /* Once per process: the registration survives fork() and
++ * coRNGInitAtFork is never reset, so repeated forks cannot stack
++ * duplicate handlers. */
++ PR_CallOnce(&coRNGInitAtFork, rng_registerAtFork);
++#endif
+ /* bytes needs to have enough space to hold
+ * a SHA256 hash value. Blow up at compile time if this isn't true */
+ PR_STATIC_ASSERT(sizeof(bytes) >= SHA256_LENGTH);
+@@ -617,6 +666,14 @@
+ PR_STATIC_ASSERT(sizeof(size_t) <= 4);
+ #endif
+
++ /* Absent before the first RNG_RNGInit(), and in a child until the
++ * inherited state is rebuilt. prng_GenerateGlobalRandomBytes() makes the
++ * same check; without it the PR_Lock() below dereferences NULL. */
++ if (globalrng == NULL) {
++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
++ return SECFailure;
++ }
++
+ PR_Lock(globalrng->lock);
+ /* if we're passed more than our additionalDataCache, simply
+ * call reseed with that data */
+@@ -736,10 +793,9 @@
+ void
+ RNG_RNGShutdown(void)
+ {
+ /* check for a valid global RNG context */
+- PORT_Assert(globalrng != NULL);
+ if (globalrng == NULL) {
+ /* Should set a "not initialized" error code. */
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return;
+ }
diff --git a/nss.spec b/nss.spec
index d4154e7..04af321 100644
--- a/nss.spec
+++ b/nss.spec
@@ -145,6 +145,10 @@ Patch66: nss-3.118-ml-dsa-tls-test.patch
Patch67: nss-3.118-ml-dsa-unittests.patch
Patch68: nss-3.123-fix-mldsa-import-regeneration.patch
+# Reseed the freebl DRBG in the child after fork(), so forked children do not
+# replay the parent's random stream (mozbz#2056509)
+Patch70: nss-3.125-drbg-reseed-after-fork.patch
+
Patch100: nspr-config-pc.patch
Patch101: nspr-gcc-atomics.patch
@@ -1096,6 +1100,10 @@ fi
* Tue Jul 28 2026 Frantisek Krenzelok <fkrenzel@redhat.com> - 3.126.0-1
- Update NSS to 3.126.0
+* Sat Jul 25 2026 Rostislav Krasny <rostiprodev@gmail.com> - 3.125.0-2
+- Reseed the freebl DRBG after fork() so forked children do not replay the
+ parent's random stream (Firefox fork server duplicate UUIDs / crypto output)
+
* Thu Jul 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 3.125.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-29 17:43 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-29 17:43 [rpms/nss] rawhide: Reseed the freebl DRBG after fork() Rostislav Krasny
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox