DF-4400 / verdict.json
{ "finding_id": "DF-4400", "status": "inconclusive", "reproduced": 0, "impact": "panic", "confidence": "certain", "verdict": "Certain from source, hardware-gated to trigger. tws_intr_resp (tws_cam.c:1170) calls sc->reqs[req_id].cb() on every firmware-supplied non-invalid req_id with no bounds check (DF-1590s index aspect) and no busy-state/completer validation. Released requests keep stale cb pointers (set at tws_cam.c:738/829/875, cleared only on re-allocation at tws.c:812), so a duplicate/stale in-range id double-completes a surrendered ccb (second xpt_done at tws_cam.c:371 + callout_stop on dead ccb memory at :365) or early-completes a reallocated in-flight ccb (biodone of live bio, DF-4178 class). tws_get_param submits reqs[3] with cb=NULL (tws_cam.c:924) and polls (:942) \u2014 an interrupt delivering that response first is a NULL function call (panic); latent today only because get_param runs at attach with interrupts masked (tws.c:547, tws_hdm.c:112-114). The drain loop also terminates only when the firmware stops producing responses. Guest lacks the 3ware HBA, so not exercisable.", "exploit_chain": "", "evidence": "VERDICT.md (lifecycle proof); fix.diff (state+bounds guard at the call site, also closing DF-1590s window here); trigger.c (response-word documentation)", "kernel_refs": [ "sys/dev/raid/tws/tws_cam.c:1161", "sys/dev/raid/tws/tws_cam.c:1170", "sys/dev/raid/tws/tws_cam.c:924", "sys/dev/raid/tws/tws.c:812", "sys/dev/raid/tws/tws.h:85" ], "poc_changes": "no seed; documentation stub only (no local trigger exists without the controller)", "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": 0, "guest_dirty": 0, "build_cmd": "cc -o trigger trigger.c", "run_cmd": "n/a \u2014 requires controller to emit duplicate/stale response", "notes": "Rated Medium consistent with DF-1590 (same device-fed trust boundary). Complements DF-1590: that finding is the OOB index; this is the missing state validation on the same walk.", "recommended_fix": "In tws_intr_resp, validate req_id < tws_queue_depth, cb != NULL and state != TWS_REQ_STATE_FREE before invoking the callback.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff adds index+state+completer validation at the response-walk call site (also closes DF-1590s window at this site); not validatable without the controller.", "fix_evidence": "fix.diff", "code_hash": "97daf986a423a81f7d2579dfff858122a55448d0f89c56555425d59ceae30506" } |