DF-4101 / verdict.json
{ "finding_id": "DF-4101", "status": "reproduced", "verdict": "REPRODUCED: the stale-callout race mechanism demonstrated deterministically on production code. A production bttimeout entered but blocked acquiring bt->lock (the exact in-progress invocation callout_stop at bt.c:1449 cannot cancel) survives the completion of its CCB (ccb-A, BMBI_OK -> CAM_REQ_CMP), the freed BCCB is recycled by production btgetccb for a new healthy command (identical bccb_kva captured), and once the lock is released the stale handler treats the NEW command as timed out: console CCB <bccb> - timed out for a command whose own 60s timer never fired, BCCB_DEVICE_RESET set, SIM queue frozen, BDR armed, and 2s later a HARD_RESET(0x80) write on the healthy bus (vhba_hard_resets 1->2) with the healthy command miscompleted CAM_CMD_TIMEOUT (0xb). The only choreographed element is the guarantee that the handler is mid-execution -- which is exactly the production contention window; all handler code is the shipped kernels.", "reproduced": true, "impact": "dos", "confidence": "certain", "exploit_chain": "bttimeout fires while a completion holds bt->lock -> handler entered, blocks at bt.c:2143 -> btdone completes+frees the CCB (callout_stop no-op against in-flight handler) -> btaction recycles the same BCCB for a new command -> stale handler acquires lock, sees BCCB_ACTIVE on the new command (bt.c:2147 cannot tell generations apart) -> freezes SIMq, stops all pending timers, arms BDR -> 2s later hard bus reset on the healthy bus + CAM_CMD_TIMEOUT miscompletions", "evidence": "run.log DF-4101 section: snap3/snap4 bccb_kva both 0xfffff801167df620; snap4 flags=0x7 timer=1 after rel with ccb-A comp=1 status=0x1; final snap4 ccb_status=0xb timer=0; console [rig] stale handler thread: calling production bttimeout(0xfffff801167df620), will block on bt->lock then CCB 0xfffff801167df620 - timed out", "kernel_refs": [ "sys/dev/disk/buslogic/bt.c:1449", "sys/dev/disk/buslogic/bt.c:2143", "sys/dev/disk/buslogic/bt.c:2147" ], "poc_changes": "race choreographed with explicit lock hold/release ioctls (the production timing window made deterministic); kthread stands in for the fired callout invocation", "attempts": 2, "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": 40, "guest_dirty": 0, "build_cmd": "./push_rig.sh", "run_cmd": "sh run1.sh", "code_hash": "745f8b43787e6bb6a37f62b8ac9fc1a99d7aab498a1faa6d34c8caeba4ba8651", "notes": "sili DF-4027 / amr DF-4060 lifecycle-race family; guest stayed up", "recommended_fix": "Generation handshake: bt_ccb gains gen/timer_gen; btgetccb bumps gen, btexecuteccb snapshots it when arming the callout, bttimeout/btdone ignore generation-mismatched invocations (fix.diff, object-compile validated)", "fix_status": "not_tested", "fix_baseline_reproduced": true, "fix_patched_reproduced": false, "fix_verdict": "object-compile validation only (race/DoS class, kernel A/B not mandated): patched bt.c+btreg.h compile clean under -Werror with kernel headers", "fix_evidence": "fix.diff; FIXED-COMPILES-CLEAN with bt.fixed.o on the guest" } |