DF-3984 / verdict.json
{ "finding_id": "DF-3984", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "ORB completion matching in sbp(4) is address-only (OCB_MATCH sbp.c:156 compares only orb_lo) and ORB slots are recycled between the management path and the command path with no generation tag (fixed slot addresses sbp.c:516-522, sbp_free_ocb sbp.c:1782). A hostile device (or hostile bus peer writing the initiator status FIFO - physical-request writes enabled by default per DF-1009) can replay a management-ORB status after its slot has been recycled into a live command ORB: recv1 misses the cleared mgm_ocb_cur, falls to sbp_dequeue_ocb (sbp.c:1605) and matches the recycled command OCB by address (sbp.c:2586), unloads its dmamap (sbp.c:2597) while the device may still be DMAing the command buffer, and completes the CCB with fully device-controlled status (sbp.c:1748-1774); the genuine completion is then dropped (sbp.c:1606-1610). Source transitions certain; the replay is standard 1394 bus capability; end-to-end untestable on this guest (no FireWire hardware) -> inconclusive, confidence likely.", "exploit_chain": "crafted SBP device: complete login on ORB slot X -> let host recycle slot X into a read command -> replay the login status (same orb_lo) -> host unloads the reads dmamap mid-DMA (device keeps writing into now-unmapped pages: disclosure into reused pages) and completes the read CAM_REQ_CMP with stale data -> repeat at will to corrupt I/O and race page reuse.", "evidence": "VERDICT.md (state-machine trace path:line); fix.diff (one-deep stale_orb_lo filter in sbp_dequeue_ocb/sbp_recv1 mgm match, patch --dry-run clean)", "kernel_refs": [ "sys/dev/disk/sbp/sbp.c:156", "sys/dev/disk/sbp/sbp.c:516", "sys/dev/disk/sbp/sbp.c:1597", "sys/dev/disk/sbp/sbp.c:1605", "sys/dev/disk/sbp/sbp.c:1782", "sys/dev/disk/sbp/sbp.c:2584", "sys/dev/disk/sbp/sbp.c:2597" ], "poc_changes": "No runnable PoC (no FireWire hardware); state machine verified by source trace.", "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 DF-2516 (payload length drives parse): this is ORB-identity/lifetime confusion; even a perfectly-formed status completes the wrong ORB.", "recommended_fix": "Record the completed mgm ORB address per LUN and drop one matching stale status before it can match a recycled command ORB (fix.diff); a protocol-complete fix needs a generation tag the SBP-2 status cannot carry.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff applies cleanly; cannot be exercised without FireWire hardware.", "fix_evidence": "fix.diff in pack" } |