DF-0084
Off-by-one OOB read in get_next_valid_apicid: array indexed before bound check in while condition
| Field | Value |
|---|---|
| ID | DF-0084 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N |
| CWE | CWE-125 Out-of-bounds Read |
| File | sys/kern/subr_cpu_topology.c |
| Lines | 91-105 |
| Area | kern (CPU topology / boot) |
| Confidence | likely |
| Discovered | 2026-06-30 |
| Reported | pending |
Summary
In get_next_valid_apicid(), the do/while condition is:
while (get_cpuid_from_apicid(next_apicid) == -1 &&
next_apicid < NAPICID); /* sys/kern/subr_cpu_topology.c:98-99 */
The array-indexing macro get_cpuid_from_apicid() is evaluated before the
bound check. When next_apicid reaches NAPICID (256), the macro expands to
apic_id_to_cpu_id[NAPICID] — one element past the end of the
int apic_id_to_cpu_id[NAPICID] array (lapic.c:122-123) — before the &&
short-circuits on next_apicid < NAPICID being false. The bogus value is
discarded (the function returns -1 at :100-103), so impact is a single 4-byte
OOB read of adjacent BSS with no control over its use.
Recommended fix
Reorder the condition to short-circuit on the bound first:
--- a/sys/kern/subr_cpu_topology.c
+++ b/sys/kern/subr_cpu_topology.c
- while(get_cpuid_from_apicid(next_apicid) == -1 &&
- next_apicid < NAPICID);
+ while(next_apicid < NAPICID &&
+ get_cpuid_from_apicid(next_apicid) == -1);
Timeline
- 2026-06-30 Discovered during automated file-by-file audit of
sys/kern/subr_cpu_topology.c. - pending Reported to DragonFlyBSD security contact.