SMAP missing from the hypervisor CPUID-feature blacklist in identify_cpu() despite the blacklist's own CR4-activation rule (buggy-hypervisor boot #GP)
Summary
The VMM blacklist masks CR4-activation-requiring extensions but only lists FSGSBASE/SMEP - SMAP qualifies under the rule's own wording (cpu_implement_smap writes CR4.SMAP) yet is never masked: a hypervisor advertising SMAP while faulting CR4.SMAP panics early boot. KVM doc-run shows the bit passing straight through under VMM (QEMU implements it so no fault - honest not_reproduced). Add-SMAP-to-blacklist fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-5346 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.2 KB | β raw | |
| VERDICT.md | β | 1.5 KB | β raw | |
| boot-kvm-smap.log | β | 12.0 KB | view raw | |
| run.sh | β | 160 B | view raw | |
| env.txt | β | 709 B | view raw | |
| fix.diff | β | 535 B | view raw | |
| verdict.json | β | 3.3 KB | view raw |
DF-5346 β SMAP missing from the hypervisor feature blacklist in identify_cpu()
Where
sys/platform/pc64/x86_64/identcpu.c
664: if (cpu_high >= 7) {
665: cpuid_count(7, 0, regs);
666: cpu_stdext_feature = regs[1];
667:
668: /*
669: * Some hypervisors fail to filter out unsupported
670: * extended features. For now, disable the
671: * extensions, activation of which requires setting a
672: * bit in CR4, and which VM monitors do not support.
673: */
674: if (cpu_feature2 & CPUID2_VMM) {
675: cpu_stdext_disable = CPUID_STDEXT_FSGSBASE |
676: CPUID_STDEXT_SMEP;
677: } else {
678: cpu_stdext_disable = 0;
679: }
The comment defines the rule: under a VMM, mask CPUID.7.EBX bits whose
activation writes a CR4 bit that VM monitors may not support. SMAP
(CPUID_STDEXT_SMAP, bit 20) qualifies exactly β its activation writes
CR4.SMAP in cpu_implement_smap() (machdep.c:344-346, invoked from
cpu_startup when cpu_stdext_feature & CPUID_STDEXT_SMAP) β but it is not
in the mask. SMEP is masked; SMAP is not. A hypervisor that advertises
SMAP without supporting CR4.SMAP (the same class of bug that motivated the
mask β VirtualBox advertising SMEP circa 2014) makes the kernel take a #GP
writing CR4 during early boot β boot panic.
On-guest documentation (QEMU 7.2.22, KVM)
-cpu qemu64,+smap,check=off boots:
Features2=0x80202001<SSE3,CX16,x2APIC,VMM> <- VMM detected Structured Extended Features=0x100000<SMAP> <- SMAP advertised under VMM CPU Special Features Installed: SMAP <- blacklist passed it through
β¦reaching login: cleanly (QEMU/KVM implements CR4.SMAP, so no fault β
expected). This documents the pass-through; the fault case requires a
CR4.SMAP-faulting hypervisor, which stock QEMU cannot emulate.
Class: defense-in-depth consistency / lying-CPUID boot DoS. Speculative β
no known shipping hypervisor currently trips it; filed because the file's
own rule says this bit belongs in the mask (and hw.cpu_stdext_disable
users can add it manually at the loader prompt).
Fix
if (cpu_feature2 & CPUID2_VMM) {
cpu_stdext_disable = CPUID_STDEXT_FSGSBASE |
CPUID_STDEXT_SMEP |
+ CPUID_STDEXT_SMAP;
}
DF-5346 β VERDICT
Status: not_reproduced (by design of the harness): the fault requires a
hypervisor that advertises CPUID.7.EBX.SMAP under the VMM bit but faults the
CR4.SMAP write. QEMU/KVM implements CR4.SMAP, so the +smap boot passes
through the blacklist and boots cleanly β which itself documents the
finding's core claim: SMAP is NOT masked under VMM while SMEP/FSGSBASE are
(identcpu.c:674-676), contradicting the mask's own rule at :668-673
("extensions, activation of which requires setting a bit in CR4").
Evidence: boot-kvm-smap.log lines 35/38/40:
Features2=0x80202001
Impact ceiling: boot-time #GP panic under a buggy/malicious hypervisor β same class as DF-5345 and the same class the in-file rdmsr_safe guard at identcpu.c:683-696 was added for. Speculative (no known shipping hypervisor currently trips it); severity Low, hardening-consistency.
Fix validation: not_testable β cannot construct the faulting hypervisor with stock QEMU 7.2 (CR4.SMAP is always accepted).
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testablenot_testable: the faulting-hypervisor precondition (CPUID.7.EBX.SMAP advertised, CR4.SMAP write faults) cannot be built from stock QEMU 7.2; on a competent hypervisor both baseline and patched kernels boot cleanly, so no behavioral delta is observable on this harness.
boot-kvm-smap.log (baseline pass-through documented); no fault observable on QEMU/KVM
Confirmed kernel references
Detail
Evidence (decisive lines)
boot-kvm-smap.log:35 (Features2=...VMM - hypervisor detected), :38 (Structured Extended Features=0x100000<SMAP> - bit survived the blacklist), :40 (CPU Special Features Installed: SMAP - cpu_implement_smap() ran); VERDICT.md
PoC changes
No seed; authored the +smap documentation boot. Expected outcome on a competent hypervisor is a clean boot - observed as such; the finding documents the missing mask, not a QEMU-reproducible fault.
Verified recommended fix
Add CPUID_STDEXT_SMAP to cpu_stdext_disable under CPUID2_VMM (one-line, see fix.diff)
Verdict
Hardening-consistency gap, honestly speculative. identify_cpu()'s hypervisor feature blacklist (identcpu.c:668-686) exists because 'Some hypervisors fail to filter out unsupported extended features' and masks CR4-activation-requiring extensions under CPUID2_VMM - but only FSGSBASE and SMEP (:675-676). SMAP qualifies under the mask's own rule (its activation writes CR4.SMAP in cpu_implement_smap(), machdep.c:344-346, reached from cpu_startup when cpu_stdext_feature & CPUID_STDEXT_SMAP) yet is not masked. On-guest documentation boot (-cpu qemu64,+smap under KVM): 'Structured Extended Features=0x100000
No comments yet.