add_buffer_randomness_src passes full remaining length (bytes) instead of chunk size (n), defeating cross-CPU entropy splitting
| Field | Value |
|---|---|
| ID | DF-0067 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N |
| CWE | CWE-682 Incorrect Calculation of Transfer Size |
| File | sys/kern/kern_nrandom.c |
| Lines | 650-668 |
| Area | kern (crypto/RNG) |
| Confidence | likely |
| Discovered | 2026-06-30 |
| Reported | pending |
Summary
add_buffer_randomness_src computes a 256-byte chunk size n (:657, capped
:662-663) to split large entropy buffers across per-CPU CSPRNG pools, but the
call at :665 passes bytes (the full remaining length) instead of n:
n = bytes; /* :657 */
...
if (n > 256) /* :662 cap for cross-CPU splitting */
n = 256;
...
add_buffer_randomness_state(state, buf, bytes, srcid); /* :665 BUG: bytes, not n */
bytes -= n; /* :666 advances by n */
buf += n; /* :667 */
Each iterated CPU receives the entire remaining suffix (CPU0=[0,total),
CPU1=[256,total), …), so the per-CPU pools get massively redundant overlapping
data instead of disjoint chunks. The comment at :638-640 ("Large amounts of
generic random data will be split across available cpus") is not honored.
No memory-safety violation: buf += n and bytes -= n advance in lockstep,
so accesses stay in-bounds. Impact is purely entropy-distribution quality: the
Fortuna-style design intention of spreading entropy sources across independent
per-CPU pools is defeated for large buffer sources (e.g. /dev/random
write-seeding up to PAGE_SIZE, TPM entropy). The RAND_SRCF_PCPU path is
unaffected (n == bytes, single iteration).
Recommended fix
--- a/sys/kern/kern_nrandom.c
+++ b/sys/kern/kern_nrandom.c
@@ -662,6 +662,6 @@
}
- add_buffer_randomness_state(state, buf, bytes, srcid);
+ add_buffer_randomness_state(state, buf, n, srcid);
bytes -= n;
buf += n;
Timeline
- 2026-06-30 Discovered during automated file-by-file audit of
sys/kern/kern_nrandom.c. - pending Reported to DragonFlyBSD security contact.