DragonFlyBSD Kernel Audit
DF-0220 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/kern/subr_csprng.c b/sys/kern/subr_csprng.c
index 0000000..1111111 100644
@@ -138,14 +138,21 @@
 
 	/*
 	 * If no reseed has occurred yet, we can't possibly give out
-	 * any random data.
-	 * If this isn't an unlimited (i.e., /dev/urandom) read, sleep
-	 * until entropy is added to the pools (or a callout-based
-	 * reseed, if enabled, occurs).
+	 * trustworthy random data: the cipher context is still in its
+	 * init-time all-zero state (chacha_keysetup() has not run yet),
+	 * whose keystream is the trivial all-zero fixed point.
+	 *
+	 * Blocking readers sleep until entropy arrives.  Non-blocking
+	 * (CSPRNG_UNLIMITED, e.g. /dev/urandom, getrandom(2), kern.random)
+	 * readers must not block -- return 0 bytes instead of emitting the
+	 * degenerate keystream, mirroring getrandom(GRND_NONBLOCK).
 	 */
-	if ((flags & CSPRNG_UNLIMITED) == 0 && state->reseed_cnt == 0) {
-		ssleep(state, &state->spin, 0, "csprngrsd", 0);
-		goto again;
+	if (state->reseed_cnt == 0) {
+		if ((flags & CSPRNG_UNLIMITED) == 0) {
+			ssleep(state, &state->spin, 0, "csprngrsd", 0);
+			goto again;
+		}
+		return 0;
 	}
 
 	while (bytes > 0) {