Latent boot-window OOB: csprng_pcpu aliases the single-element csprng_boot while APs are up, and read_random/add_buffer_randomness_src index it with unclamped gd_cpuid
| Field | Value |
|---|---|
| ID | DF-2822 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:N/A:N |
| CWE | CWE-125 (latent; writes follow via spin_lock/IBAA mutation) |
| File | sys/kern/kern_nrandom.c |
| Lines | 495-500 (consumers :659, :697; array at :562) |
| Area | kern |
| Confidence | certain |
| Discovered | 2026-08-31 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:kern |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
rand_initialize() installs csprng_pcpu = &csprng_boot (exactly one
struct) from init_x86_64 while ncpus==1. The per-cpu array only appears
at a later SYSINIT. Between SI_BOOT2_START_APS and that SYSINIT,
ncpus>1 and any execution of read_random()'s state =
&csprng_pcpu[mycpu->gd_cpuid] or add_buffer_randomness_src()'s PCPU
branch on cpu>0 addresses memory past csprng_boot and would
spin_lock/mutate adjacent .bss — silent kernel memory corruption. On
the current tree the window is empty of RNG consumers (verified by
enumerating every call site and its SYSINIT ordering); one new
early-boot RNG consumer away from real corruption.
Recommended fix
Clamp or gate until the array exists (fall back to &csprng_boot when csprng_pcpu == &csprng_boot and gd_cpuid != 0), or allocate the real array before SI_BOOT2_START_APS.
Timeline
- 2026-08-31 Discovered during pass-2 audit of kern_nrandom.c (GLM 5.3).
No comments yet.