DF-3985 / verdict.json
{ "finding_id": "DF-3985", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "sbp_free_target() (sbp.c:1993-2014) early-returns when target->luns == NULL without clearing target->fwdev or stopping target->scan_callout. sbp_alloc_target (sbp.c:544-589) installs fwdev with luns==NULL before any LUN exists, so a device whose Config ROM has a management agent but no CROM_LUN keys leaves the slot in that state; every later free (post_explore GC sbp.c:776-786, num_lun==0 sbp.c:816-817, detach sbp.c:2040-2041) hits the early return. sbp_new_target only reuses fwdev==NULL slots (sbp.c:393-394), so 8 rounds of hostile device churn (new EUI-64 each) exhaust SBP_NUM_TARGETS -> permanent SBP attach DoS until reboot, each dead slot holding a dangling fw_device that firewire.c kfrees after hold_count missed resets (firewire.c:1600-1611). Additionally, in the window before GC (and indefinitely for stuck slots), armed mgm_ocb_timeout (sbp.c:1351, body sbp.c:2126-2146 -> sbp_reset_start -> sbp_write_cmd) and injected status packets for the dead targets FIFO address dereference the freed fw_device (fwdev->speed sbp.c:1256, fwdev->dst sbp.c:1273). End-to-end inconclusive: guest has no FireWire controller (../DF-3981/env.txt); the leak control-flow is source-certain.", "exploit_chain": "crafted FireWire device churn x8 -> all 8 target slots leaked with dangling fwdev -> no SBP storage attachable until reboot (DoS); transient freed-slab reads leak bus-relevant fields into packet setup.", "evidence": "VERDICT.md (control-flow proof of the leak + deref windows); fix.diff (restructure sbp_free_target: stop both callouts, clear fwdev on all exits - patch --dry-run clean)", "kernel_refs": [ "sys/dev/disk/sbp/sbp.c:1993", "sys/dev/disk/sbp/sbp.c:1998", "sys/dev/disk/sbp/sbp.c:586", "sys/dev/disk/sbp/sbp.c:816", "sys/dev/disk/sbp/sbp.c:776", "sys/dev/disk/sbp/sbp.c:393", "sys/dev/disk/sbp/sbp.c:1256", "sys/dev/disk/sbp/sbp.c:1273", "sys/bus/firewire/firewire.c:1600" ], "poc_changes": "No runnable PoC (no FireWire hardware); leak proven by pure control-flow trace in VERDICT.md.", "attempts": 0, "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": 0, "guest_dirty": 0, "build_cmd": "", "run_cmd": "", "code_hash": "", "notes": "fix.diff is the sbp_free_target half of DF-3981s fix (kept standalone; the two fixes land together cleanly).", "recommended_fix": "Restructure sbp_free_target so callout_stop(scan+mgm) and fwdev=NULL run on every exit path; wrap luns-dependent teardown in if (luns != NULL) (fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff applies cleanly; runtime validation needs FireWire hardware absent from the guest.", "fix_evidence": "fix.diff in pack" } |