{
  "finding_id": "DF-5160",
  "status": "reproduced",
  "reproduced": true,
  "impact": "panic",
  "confidence": "likely",
  "verdict": "reproduced (driver-level): aperf_sensor_task() reads MSR_IA32_APERF(0xE8)/MSR_IA32_MPERF(0xE7) with the raw fault-unsafe rdmsr (aperf.c:159-160) every second (task period 1, aperf.c:131; first invocation already performs the reads), gated only by the live CPUID.06H.ECX bit0 check in aperf_identify (aperf.c:88-90) with no cpu_high guard (contrast perfbias.c:99) and no fault-safe accessor - the DF-4735/DF-5155 lying-CPUID class. Guest proof chain on KVM: (1) stock aperf.ko built -Werror from the unmodified guest source (md5 efc02589720a8f59311a7d396ed325b2 == audit tree) loads but never attaches on either CPU model because KVM presents CPUID.06H ECX=0 even under -cpu host (approbe: max basic leaf 0x16, 06H EAX=4 ECX=0) exactly because it does not virtualize the MSR - while rdmsr_safe(0xE7/0xE8) returns EFAULT(14) on both models; (2) trigger module aptest.ko executing the verbatim aperf.c:157-161 body incl. crit_enter(): Fatal trap 9: general protection fault while in kernel mode ... current thread = pri 6 (CRIT) ... Stopped at aptest_modevent+0xd2: rdmsr, guest dead in DDB (run.log/panic.txt); (3) DRIVER-LEVEL: lie.ko force-adds aperf children to the cpu devices (the DF-4735-documented CPUID-advertisement substitution, nothing else) - the stock unmodified driver attaches (aperf0..aperf5 CPU Frequency Sensor on cpuN) and its REAL task traps: Stopped at aperf_sensor_task+0x48: rdmsr, guest dead (run.2.log/panic2.txt). On any VMM/CPU that advertises ECX bit0 without implementing the MSR, a kernel with device aperf therefore panics ~1s after boot with zero user interaction. Reachability is weaker than DF-4735/DF-5155: aperf is NOT in X86_64_GENERIC (LINT64:1670 only), so it needs a custom/LINT kernel or a root kldload - Low severity, privileged/boot-time DoS, no privilege boundary crossed. Fix build- and boot-validated: fix.diff (cpu_high guard + rdmsr_safe pair, skip sample on fault) applied to guest /usr/src, patched driver built -Werror, force-attached via the same lie.ko on the same faulting platform: all 6 CPUs attach, tasks fire every second, NO trap, guest stays up, hw.sensors.cpuN.freq0 correctly held unknown (run.3.log); apfix.ko replicating the patched body prints rdmsr_safe(MSR_APERF)=14 -> sample skipped, NO TRAP.",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-5160/run.log + panic.txt (qemu64: safe reads EFAULT=14 then Fatal trap 9 at the verbatim aperf.c:157-161 body, thread pri 6 CRIT); run.2.log + panic2.txt (-cpu host Skylake: stock driver force-attached via lie.ko, Stopped at aperf_sensor_task+0x48: rdmsr); stock_driver_gate.log + run.2.log approbe lines (KVM strips ECX bit0 on both CPU models while rdmsr_safe returns 14 - the masking policy that demonstrates the lying-CPUID class); run.3.log (patched driver, same force-attach, no trap, guest alive, sensors unknown); aptest.c/approbe.c/lie.c/apfix.c/aperf_fixed.c + build.sh/run.sh + build.log (-Werror); fix.diff (git apply --check clean); env.txt/env.2.txt",
  "kernel_refs": [
    "sys/dev/misc/aperf/aperf.c:159",
    "sys/dev/misc/aperf/aperf.c:160",
    "sys/dev/misc/aperf/aperf.c:88",
    "sys/dev/misc/aperf/aperf.c:90",
    "sys/dev/misc/aperf/aperf.c:131",
    "sys/cpu/x86_64/include/cpufunc.h:528",
    "sys/cpu/x86_64/include/cpufunc.h:1004",
    "sys/dev/powermng/perfbias/perfbias.c:99",
    "sys/config/LINT64:1670"
  ],
  "poc_changes": "no seed pack existed for this file; all trigger sources authored fresh: aptest.c (verbatim task body incl. crit_enter/crit_exit), approbe.c (non-fatal gate/safe-read probe), lie.c (newbus force-attach via devclass_find(\"cpu\") + device_add_child + device_probe_and_attach, substituting only the missing CPUID advertisement per the DF-4735 technique), apfix.c (patched-body replica). lie.ko needs SRCS+= bus_if.h device_if.h under bsd.kmod.mk (first build failed without them, fixed).",
  "attempts": 3,
  "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 (qemu64 and -cpu host=Intel Xeon E3-1275 v5 runs)",
  "runtime_sec": 1800,
  "guest_dirty": 0,
  "build_cmd": "guest, per module: mkdir -p /root/df5160/<dir>; printf KMOD=\\t<name>\\nSRCS=\\t<srcs>\\nCFLAGS+=\\t-Werror\\n\\n.include <bsd.kmod.mk>\\n > Makefile; make SYSDIR=/usr/src/sys   (aptest/approbe/apfix: SRCS=<x>.c; lie: SRCS=lie.c bus_if.h device_if.h; aperf: SRCS=aperf.c bus_if.h device_if.h cpu_if.h)",
  "run_cmd": "kldload aperf.ko (stock, gate observed closed) ; kldload aptest.ko (trigger: EFAULT x2 then Fatal trap 9) ; kldload lie.ko (driver-level: Stopped at aperf_sensor_task+0x48: rdmsr) ; fix validation: patched aperf.ko + lie.ko -> no trap, guest up",
  "code_hash": "96bcef2995ef68c76928e0a116d4a85ba64091c41e9ce2a1909fde35bd45d99e",
  "notes": "div0 guarded (aperf.c:183-184); no detach UAF (kern_sensors.c:264-266 vs :307/:328-331/:334 - unregister2 holds the same thr->lock the task thread runs func under, and re-entry is gated on the running flag); CPU_GET_SENSDEV NULL-checked (aperf.c:118-120); sensor_task_register2 M_WAITOK cannot fail; freq-math overflow at worst mis-reports a number. panic2.txt lacks the Fatal trap banner because six per-CPU tasks faulted within the same second and the concurrent DDB entries garbled the console; the stop line names the stock function. KVM masks ECX bit0 on both qemu64 and -cpu host while the MSRs fault with EFAULT - i.e. the only protection is the CPUID bit VMM vendors strip precisely because the MSR is not virtualized.",
  "recommended_fix": "aperf_sensor_task: replace the raw pair with rdmsr_safe(MSR_APERF/MSR_MPERF), returning (skipping the sample) on fault; add cpu_high >= 6 guard (+#include <machine/md_var.h>) before do_cpuid(6) in aperf_identify, mirroring perfbias.c:99.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "baseline reproduced twice (trigger-level Fatal trap 9 at the verbatim instruction body, run.log; driver-level Stopped at aperf_sensor_task+0x48: rdmsr in the stock unmodified driver force-attached via the CPUID-substitution kld, run.2.log); fix.diff (git apply --check clean) applied to the guest /usr/src copy, patched aperf.ko built clean under -Werror, and the identical force-attach on the identical faulting platform yields: all six CPUs attached, 1s-period sensor tasks running continuously, NO trap, guest stays up, sensors correctly held at unknown (hw.sensors.cpuN.freq0) because the patched task skips the sample when rdmsr_safe returns EFAULT (run.3.log; apfix.ko prints the same semantics standalone). fix_patched_reproduced=false means exactly: the patched driver does NOT reproduce the panic - the bad behavior is gone.",
  "fix_evidence": "findings/poc/DF-5160/fix.diff; run.3.log (patched driver + lie.ko force-attach on -cpu host: aperf0..5 attached rc=0, apfix sample skipped, NO TRAP, guest alive); baseline run.2.log/panic2.txt (Stopped at aperf_sensor_task+0x48: rdmsr); build.log for the -Werror builds"
}