⬢ DragonFlyBSD Kernel Audit
DF-4369 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4369",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Real race, hardware-gated: hpt_timeout() (hpt27xx_osm_bsd.c:411-419, softclock, no lock) dereferences pCmd->priv after the completion path os_cmddone() (:421-466) callout_stop()s the timer and frees both the OS_CMDEXT (:463) and the PCOMMAND (:464). DragonFly callout_stop() explicitly does not interlock against a callout that is in-progress (sys/kern/kern_timeout.c:1087-1088), so a timeout firing on another CPU at the completion instant reads a freed/recycled command: if the block was recycled as a flush command priv points at a kernel stack variable (&done, :303) and ldm_reset_vbus() receives a wild pointer -> fatal trap (panic/DoS, no write primitive). Requires a RocketRAID 27xx controller; the audit guest has none (pciconf shows no vendor 0x1103 device; dmesg: hpt27xx: no controller detected.), so the race could not be executed there \u2014 classification is not_reproduced with the static proof chain in the evidence pack carrying the finding.",
  "exploit_chain": "",
  "evidence": "race_proof.txt (arm/completion/timeout interleaving table with path:line); VERDICT.md; run.log line hpt27xx: no controller detected. proving the guest cannot reach the code; fix.diff (lock+revalidate fix)",
  "kernel_refs": [
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:411",
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:414",
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:418",
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:421",
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:428",
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:463",
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:464",
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:530",
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:730",
    "sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c:303",
    "sys/dev/raid/hpt27xx/os_bsd.h:190",
    "sys/dev/raid/hpt27xx/him.h:417",
    "sys/kern/kern_timeout.c:1087"
  ],
  "poc_changes": "No seeded PoC existed. Wrote an environment-probe script (verify_env.sh/run.sh) and a disassembly-verified negative-analysis appendix (race_proof.txt) covering the blobs GET_LOGICAL_DEVICES clamping (min(total,maxcount) at .text 0x77330/0x7f1c0), which killed a candidate stack-overflow theory.",
  "attempts": 1,
  "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": 95,
  "guest_dirty": 0,
  "build_cmd": "nothing to build (driver compiled into X86_64_GENERIC; no hardware to exercise)",
  "run_cmd": "dfbsd-qemu/vm.sh run_root pciconf -l; kldstat -v | grep hpt27xx; ls /dev/hpt27xx; dmesg | grep hpt  (== ./run.sh)",
  "code_hash": "4e46e66352d1856483b46c3fefc5f28b4b288e0c722f9f2f1ba77b64c410f094",
  "notes": "Hardware-gated finding (RocketRAID 27xx, vendor 0x1103): guest PCI bus has only i440FX/PIIX4/bochs-VGA/virtio, driver compiled in but never attaches (hpt_final_init:1021 no controller detected.), no /dev/hpt27xx, no CAM sim \u2014 the racing paths are unreachable on this guest. Static impact on hardware-equipped SMP systems: kernel panic (DoS) when a command completes in the same instant its 20s HPT_OSM_TIMEOUT expires and the freed PCOMMAND is recycled; no write primitive, no escalation. Field symptom: sporadic fatal trap in hpt_timeout on storage boxes with a stalling disk. Same-file negatives proven during this pass are documented in race_proof.txt (count-shuffle clamped by the binary lib; cmdext NULL impossible via devq accounting; flush/ioctl sleep loops lost-wakeup-safe; KdPrint/HPT_ASSERT compile to no-ops in release; ioctl kmalloc sizes root-only-0600 gated).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored (hpt_timeout takes the recursive vbus lock and re-validates pCmd->priv==ext and pCmd->done==os_cmddone before resetting). Cannot be build-validated on the audit guest: no HighPoint controller, and reproducing the baseline race itself requires one. callout_stop_sync() was deliberately avoided \u2014 os_cmddone runs in interrupt context while hpt_timeout needs the same vbus lock, so a synchronizing stop would deadlock.",
  "fix_evidence": "fix.diff; VERDICT.md Fix section",
  "recommended_fix": "In hpt_timeout(), take the (recursive) vbus lock and re-validate that pCmd still belongs to this completion path (pCmd->done == os_cmddone && pCmd->priv == ext) before calling ldm_reset_vbus(), so a timeout racing os_cmddones callout_stop/free cannot dereference a recycled PCOMMAND."
}