β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-5346

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-5346 Β· 7 files
FileTypeDescriptionSize
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;
        }
VERDICT.md
↓ download raw

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 (VMM present) Structured Extended Features=0x100000 (bit survived the blacklist) CPU Special Features Installed: SMAP (cpu_implement_smap() ran)

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_testable
baseline no→ patch + rebuild →patched clean

not_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
↓ fix.diffper-fix-DF-5346

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' with VMM bit set, blacklist passed it through, 'CPU Special Features Installed: SMAP', CR4.SMAP accepted, clean boot - proving the pass-through claim; the fault case (hypervisor advertising SMAP but faulting CR4.SMAP writes) panics the kernel during early boot but cannot be constructed with stock QEMU 7.2 (CR4.SMAP is always accepted), so the panic is not reproduced. Impact ceiling: boot-time #GP kernel panic under a buggy/malicious hypervisor - the same class the in-file comment describes; Low severity because no shipping hypervisor is known to trip it today and operators can add the mask via hw.cpu_stdext_disable.