⬢ DragonFlyBSD Kernel Audit
DF-4928 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4928",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Reproduced live on the DragonFly 6.5-DEVELOPMENT audit guest (QEMU/KVM, CPUID Origin=GenuineIntel Family=0xf Model=0x6b): corepower_probe() accepts a non-family-06 CPU because the model whitelist at corepower.c:165-197 is a skip-guard (the switch is simply not entered for family != 6) rather than a reject, leaving rdmsr_safe(MSR_RAPL_POWER_UNIT) via corepower_try() (:199) as the only gate - which this VMM passes since it services the MSR. attach() then executes the raw rdmsr() at :273 and returns ENXIO at :331-332 (sc_have_sens==0). dmesg pair corepower0: <CPU On-Die Power Usage Estimation> on cpu5 / device_probe_and_attach: corepower0 attach returned 6 captured in run.log; no sensors, no #GP, kldload/kldunload clean, guest alive. Impact none: every sensor MSR is individually rdmsr_safe-verified at attach before the refresh paths raw reads (:289-329 gate :393/:402), so no panic path is reachable - this is a hardening finding recording the gating shape (the coretemp DF-4735 #GP family pattern) plus the raw-rdmsr-where-rdmsr_safe-was-available miss at :273.",
  "exploit_chain": "",
  "evidence": "run.log: CPU line Origin=\"GenuineIntel\" Id=0x60fb1 Family=0xf Model=0x6b followed by kldload -> corepower0: <CPU On-Die Power Usage Estimation> on cpu5 + device_probe_and_attach: corepower0 attach returned 6, (no sensors - as expected), clean kldunload, uptime OK. env.txt: guest uname + hw.model + dev_idmax.",
  "kernel_refs": [
    "sys/dev/powermng/corepower/corepower.c:165-197",
    "sys/dev/powermng/corepower/corepower.c:199",
    "sys/dev/powermng/corepower/corepower.c:273",
    "sys/dev/powermng/corepower/corepower.c:331-332"
  ],
  "poc_changes": "Authored from scratch (Info finding; no prior sketch). Trigger is a pure shell sequence: kldload corepower as root, capture dmesg/sysctl, kldunload, uptime.",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "runtime_sec": 60,
  "guest_dirty": 0,
  "build_cmd": "sh build.sh (no-op; kernel module shipped as /boot/kernel/corepower.ko)",
  "run_cmd": "sh trigger.sh (as root)",
  "code_hash": "none (shell trigger)",
  "notes": "Everything else in corepower.c audited clean in this pass: identify child_no check is a child-COUNT guard (subr_cpu_topology.c:122-133), not an inverted chip filter; detach ordering safe because kern_sensors runs callbacks under thr->lock and sensor_task_unregister2 takes the same lock (kern_sensors.c:300-339, :252-266); no div-by-zero (secs literal 1); 32-bit energy-wrap delta bounded <= 0xFFFFFFFF so no u64->u32 truncation; sysctl strings ksnprintf-bounded; sensor_task_register2 cannot fail with M_WAITOK so unregister2(NULL) unreachable.",
  "recommended_fix": "Reject non-Intel/non-family-06 CPUIDs explicitly at the top of corepower_probe() and use rdmsr_safe() for MSR_RAPL_POWER_UNIT in corepower_attach() (fix.diff).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": null,
  "fix_verdict": "Two-line hardening (fix.diff, applies clean via patch --dry-run). No kernel rebuild/validation performed: Info-severity finding, and per contract a single-fix kernel build is mandated only for reproduced memory-corruption findings. The patched behavior is trivially predictable (probe returns ENXIO for family != 6 before any attach attempt).",
  "fix_evidence": "fix.diff hunks at corepower.c:159 and :275; baseline behavior in run.log."
}