get_next_valid_apicid() -1 sentinel propagated unvalidated into get_cpuid_from_apicid(-1): OOB read of apic_id_to_cpu_id[-1] whose value is used, plus duplicate leaf member masks on exhaustion
| Field | Value |
|---|---|
| ID | DF-2847 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L |
| CWE | CWE-125 / CWE-20 (unchecked sentinel) |
| File | sys/kern/subr_cpu_topology.c |
| Lines | 100-103, 131-132 |
| Area | kern |
| Confidence | likely |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:kern |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
When the leaf count of the built tree exceeds the number of registered valid APIC IDs, get_next_valid_apicid() returns β1. The caller stores the sentinel and immediately calls get_cpuid_from_apicid(β1) = apic_id_to_cpu_id[β1] β a 4-byte OOB read BEFORE the array (adjacent BSS) whose value, unlike DF-0084's discarded read, is USED as the bit index for CPUMASK_ASSBIT. Memory-safety is contained only by the cpumask element-index masking, so the result is a wrong members bit; the next leaf's call re-walks and builds duplicate member masks (two nodes claim the same CPU). Reachable only with malformed firmware/hypervisor tables (duplicate MADT APIC IDs, x2APIC IDs β₯ NAPICID, mptable HT-fixup inflation). Hostile hypervisor/crafted firmware at boot; no user-triggerable path, no uid=0 route.
Recommended fix
Validate the sentinel before use in build_topology_tree's leaf path (row diff) + apply DF-0084's condition reorder.
Timeline
- 2026-09-02 Discovered during pass-2 audit of subr_cpu_topology.c (GLM 5.3); source-proven (firmware-gated).
No comments yet.