DF-0220 / fix.diff
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) { |