DF-3983 / verdict.json
{ "finding_id": "DF-3983", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "sbp_orb_pointer()s fw_asyreq failure branch (sbp.c:1175-1179) completes the CCB (xpt_done) but leaves the OCB linked on sdev->ocbs, leaves ocb->ccb set, leaves the CCB timeout callout armed (sbp.c:2640-2643) and the data dmamap loaded. fw_asyreq fails immediately and attacker-influenceably (AT queue full EINVAL firewire.c:230-235; tlabel exhaustion EIO firewire.c:240-242 - both sustainable by a hostile 1394 peer via split-transaction/ack-busy pressure). Every later completion of that ORB then completes the CCB a second time: the timeout arm (sbp_timeout -> sbp_abort_all_ocbs -> sbp_abort_ocb, xpt_done at sbp.c:2707 on the stale ocb->ccb) or the device arm (sbp_dequeue_ocb still matches the queued OCB; recv1 xpt_done at sbp.c:1774) - double xpt_done on a CAM-completed/freed ccb, plus a duplicate free_ocbs insertion when both arms free the same OCB, which makes two future commands share one OCB. Source-certain; end-to-end inconclusive because the audit guest has no FireWire controller (../DF-3981/env.txt) so the path cannot be entered.", "exploit_chain": "hostile 1394 peer saturates tlabels/AT queue while local I/O runs on an SBP device -> fw_asyreq(EINVAL/EIO) at sbp.c:1175 -> premature xpt_done; OCB stays queued+armed -> device answers or timeout fires -> second xpt_done (CAM UAF) and/or double sbp_free_ocb -> free_ocbs cycle -> two commands share an OCB -> cross-ccb corruption.", "evidence": "VERDICT.md (both double-completion arms traced path:line); fix.diff (dequeue + sbp_abort_ocb exactly-once routing, patch --dry-run clean)", "kernel_refs": [ "sys/dev/disk/sbp/sbp.c:1175", "sys/dev/disk/sbp/sbp.c:2637", "sys/dev/disk/sbp/sbp.c:2640", "sys/dev/disk/sbp/sbp.c:2684", "sys/dev/disk/sbp/sbp.c:2705", "sys/dev/disk/sbp/sbp.c:1774", "sys/bus/firewire/firewire.c:230", "sys/bus/firewire/firewire.c:240" ], "poc_changes": "No PoC: requires FireWire hardware absent from the guest; fw_asyreq immediate-failure paths verified in firewire.c source instead.", "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": "Distinct from known DF-2515 (CDB overflow) and DF-2516 (payload length): this is the command-submission error paths completion discipline.", "recommended_fix": "In sbp_orb_pointers fw_asyreq failure branch, STAILQ_REMOVE the ocb from sdev->ocbs and complete via sbp_abort_ocb (dmamap unload + timeout stop + single xpt_done + single free) - fix.diff.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff applies cleanly; runtime validation impossible on this guest (no FireWire hardware to induce fw_asyreq failure).", "fix_evidence": "fix.diff in pack" } |