⬢ DragonFlyBSD Kernel Audit
DF-4335 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4335",
  "status": "untested",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Kernel path not runnable on this guest (no 3ware 9000-series hardware: no /dev/twa*, 0 PCI 13c1 devices), but the defect is a deterministic single-threaded logic error, and its queue-corruption mechanism was reproduced on the guest with the drivers own TW_CL_Q_* list macros: after a 60s poll timeout of a PENDING internal request, tw_cli_get_param/tw_cli_set_param insert the request into FREE_Q a second time (helper already inserted it at tw_cl_io.c:1029), producing an unwalkable self-looped free queue (in-kernel: unbounded spin while holding the gen_lock spinlock) and repeated handout of the same request context to two owners; the BUSY-timeout variant leaves one request simultaneously in BUSY_Q and FREE_Q, so its cmd_pkt DMA buffer is rebuilt under live firmware ownership and the late response completes the wrong request including a 1024-byte copyback into a foreign OSL buffer (tw_cl_intr.c:407-416). Sibling of DF-1814/DF-4274 at a distinct site in this file.",
  "exploit_chain": "3ware controller present + internal get/set_param poll request times out (wedged/slow firmware at attach or during controller reset; no ioctl needed) -> FREE_Q double-insert or BUSY+FREE dual membership -> (a) any CPU touching a CL request queue spins forever on gen_lock (hard wedge), or (b) same request context handed to two owners -> cmd_pkt rewritten while firmware owns the DMA -> late firmware response completes the wrong request -> 1024-byte firmware-controlled copyback into wrong kernel buffer. Not exercisable on this guest.",
  "evidence": "run.log (guest-executed model reproducer: Case 1 INFINITE CYCLE + handed out 2 time(s), Case 2 dual-queue membership, Case 3 fixed-sequence clean); VERDICT.md (line-by-line trace); fix.diff (git-apply-valid against sys/)",
  "kernel_refs": [
    "sys/dev/raid/twa/tw_cl_io.c:781",
    "sys/dev/raid/twa/tw_cl_io.c:812",
    "sys/dev/raid/twa/tw_cl_io.c:899",
    "sys/dev/raid/twa/tw_cl_io.c:929",
    "sys/dev/raid/twa/tw_cl_io.c:999",
    "sys/dev/raid/twa/tw_cl_io.c:1029",
    "sys/dev/raid/twa/tw_cl_intr.c:407",
    "sys/dev/raid/twa/tw_cl_misc.c:140",
    "sys/dev/raid/twa/tw_cl.h:270"
  ],
  "poc_changes": "No hardware PoC possible; authored a deterministic logic-model reproducer using the drivers verbatim TW_CL_Q_* macros (tw_cl_share.h) modeling submit_and_polls timeout tail vs get/set_params out: path; bounded the queue walkers with cycle guards so the (deliberately corrupted) list walk terminates and reports the cycle instead of hanging.",
  "attempts": 3,
  "guest_uname": "DragonFly dfbsd 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": 900,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o poc_dblinsert poc_dblinsert.c",
  "run_cmd": "./poc_dblinsert",
  "code_hash": "313a78085b9c5092fc6ed5954fc25d82239d20a6026e90d6edb609d2b0526f7d",
  "notes": "Device is 0600 root:operator (tw_osl_freebsd.c:405) but the trigger needs no ioctl: attach-time notify_ctlr_info get_param or reset-time SYNC_TIME set_param with a wedged firmware suffices. Poll-mode requests run only while controller interrupts are torn down, so the code comments Need to revisit ISR race is unreachable; this finding needs no race at all.",
  "recommended_fix": "get_param/set_param out: paths must not re-queue (nor clear internal_req_busy) on TW_OSL_ETIMEDOUT; give BUSY-timed-out poll-mode requests a tw_cli_poll_requeue_callback so the next reset drain re-queues them exactly once (fix.diff).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Kernel fix validation impossible on this guest (no twa hardware). fix.diff is git-apply-valid against sys/; the model reproducers Case 3 demonstrates the patched call sequence restores single-queue membership in both timeout variants.",
  "fix_evidence": "findings/poc/DF-4335/fix.diff (git apply --check PASS); run.log Case 3 lines"
}