⬢ DragonFlyBSD Kernel Audit
DF-4178 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4178",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Source-certain use-after-release/double-queue in the twe request state machine: twe_immediate_request (twe.c:981) returns after its 5s poll with the request still posted to the controller and linked on twe_busy; every caller (twe_get_param twe.c:826, twe_set_param twe.c:909, twe_dump_blocks twe.c:506, twe_init_connection twe.c:946) then calls twe_release_request, double-linking the request (busy+free). A late completion twe_done (twe.c:1199) falls through the nonbusy print: it clobbers the reused requests status, executes twe_remove_busy (twe.c:1209) on a request not on the busy queue (TAILQ writes through stale linkage pointers) and can fire the new owners completion callback (biodone on an in-flight bio). Not exercisable on this guest: no 3ware Escalade controller (no /dev/tweN; PoC open() = ENOENT, see run.log); the control node is additionally 0600 root:operator (twe_freebsd.c:339). Trigger on affected HW: any parameter/init/dump command that exceeds the 5s poll (controller busy rebuilding / faulted) and completes afterwards.",
  "exploit_chain": "",
  "evidence": "VERDICT.md (step-by-step path:line trace); twe_getparam_timeout.c (trigger); run.log (hardware absent, build OK); fix.diff + fix_build.log (fix compiles -Werror in kernel and module)",
  "kernel_refs": [
    "sys/dev/raid/twe/twe.c:981",
    "sys/dev/raid/twe/twe.c:1003",
    "sys/dev/raid/twe/twe.c:1010",
    "sys/dev/raid/twe/twe.c:826",
    "sys/dev/raid/twe/twe.c:909",
    "sys/dev/raid/twe/twe.c:506",
    "sys/dev/raid/twe/twe.c:946",
    "sys/dev/raid/twe/twe.c:1199",
    "sys/dev/raid/twe/twe.c:1209",
    "sys/dev/raid/twe/twevar.h:249"
  ],
  "poc_changes": "n/a (first-pass PoC authored in this run; self-contained ioctl definitions, builds clean with -Wall on the guest)",
  "attempts": 1,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 x86_64",
  "runtime_sec": 20,
  "guest_dirty": 1,
  "build_cmd": "cc -O -Wall -o twe_getparam_timeout twe_getparam_timeout.c",
  "run_cmd": "./twe_getparam_timeout /dev/twe0 1000",
  "code_hash": "3d9fe1665fe2d780dada30f1944872c50f81e28937709b9b28713385c85a648e",
  "notes": "HW-gated (3ware 13c1:1000/1001) + root-gated (control node 0600). Related but distinct: twe_wait_request (twe.c:969) has no timeout at all - a hung controller wedges TWEIO_COMMAND callers forever, each consuming one of 255 requests. Residual after fix: caller still frees the 512B param buffer the controller may late-write; full fix needs TWE_OP_ABORT before free.",
  "recommended_fix": "On timeout, twe_immediate_request must unmap + dequeue (twe_remove_busy) + mark TWE_CMD_ERROR the request before returning, and twe_done must consume-and-drop stale responses for nonbusy requests instead of falling through.",
  "fix_status": "inconclusive",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Compile-validated only: fix.diff (two hunks) applied cleanly to the guest /usr/src and batch-built into X86_64_GENERIC with -Werror (twe.c both in-kernel and as module), rc=0, zero errors - see fix_build.log. Behavioral validation impossible on this guest (no 3ware controller).",
  "fix_evidence": "fix_build.log (excerpt; full log findings/poc/_batch4178-4182/fix_build.log): twe.c compiled with -Werror in-kernel and KLD_MODULE; Kernel build for X86_64_GENERIC completed."
}