{
  "finding_id": "DF-4237",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Code-trace proven; not live-triggerable on the audit guest because no sili(4) HBA exists there (device-absent, not a false positive): sili_ata_get_xfer() returns NULL when the ccb free list is empty (sili.c:2318-2327 -> 2003-2018), and sili_cam.c dereferences the result unconditionally - xa->complete write at sili_cam.c:290 (IDENTIFY, reached from XPT_PATH_INQ-wildcard / XPT_ENG_EXEC / port-thread probes which hold no devq credit, sili_cam.c:846-850,878-881, sili.c:511-512) and xa->tag read at sili_cam.c:372 (NCQ renegotiation loop, reached from the XPT_SCSI_IO reprobe path sili_cam.c:944-945). The loop permanently holds every free slot with tag >= at_ncqdepth (sili_cam.c:370-376) and drains the pool: with 29 in-flight ccbs and a device re-reporting qdepth=1 (at_ncqdepth=2, only tag 0 cycles), iteration 2 gets NULL and the kernel faults on the NULL direct-map page -> panic. sili_port_softreset success sets ap_probe=NEED_IDENT without revoking in-flight ccbs (sili.c:845-849), which is the natural entry to the race after error recovery / XPT_RESET_DEV.",
  "exploit_chain": "saturated NCQ queue (30 CAM ccbs hold xas) + reprobe event (error-recovery softreset / camcontrol reset / hot-plug glitch sets NEED_IDENT) -> next XPT_SCSI_IO (or PATH_INQ/ENG_EXEC/port-thread) runs sili_cam_probe -> NCQ renegotiation loop holds the last free slot (device-fed qdepth=1 -> at_ncqdepth=2) -> sili_ata_get_xfer returns NULL -> xa->tag read through NULL at sili_cam.c:372 -> kernel page fault on NULL direct-map -> panic (local DoS; crafted-SATA-disk threat model triggers deterministically, same family as DF-3690../DF-4027).",
  "evidence": "run.log: guest-built model, shipped mode prints PANIC: sili_cam.c:372 xa->tag read through NULL xa after loop held 1 slots (iteration 2/31) and exits 3; guard mode (fix.diff semantics) defers with no panic; Scenario C idle-port control shows no NULL without concurrency. VERDICT.md has the full line-cited trace; env.txt documents the absent SiI hardware on the guest.",
  "kernel_refs": [
    "sys/dev/disk/sili/sili_cam.c:289-294",
    "sys/dev/disk/sili/sili_cam.c:365-381",
    "sys/dev/disk/sili/sili_cam.c:944-945",
    "sys/dev/disk/sili/sili_cam.c:1026",
    "sys/dev/disk/sili/sili_cam.c:1420",
    "sys/dev/disk/sili/sili.c:2003-2018",
    "sys/dev/disk/sili/sili.c:2318-2327",
    "sys/dev/disk/sili/sili.c:511-512",
    "sys/dev/disk/sili/sili.c:845-849"
  ],
  "poc_changes": "No seed PoC; sili_ncq_pool_model.c is a userspace model of the exact pool rules (31 slots, slot 1 err-reserved, TAILQ head-pop/tail-push, devq opening 30, renegotiation loop semantics), run on the guest in both shipped and guarded modes.",
  "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": 1,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o sili_model sili_ncq_pool_model.c",
  "run_cmd": "./sili_model; ./sili_model guard",
  "code_hash": "a2a2a08389197b1d13f6f9c0dffd4d7ca6d861ef7a438216272b5bf29a00efa4",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "not_testable on the guest (no sili HBA to build a kernel for); fix.diff adds NULL guards at sili_cam.c:289 (return EBUSY keeping NEED_IDENT so the probe retries), :371 (break out of the renegotiation loop when the pool is drained), and defensive CAM_RESRC_UNAVAIL completions at :1026/:1420; guards are modeled by ./sili_model guard which defers both panic scenarios with exit 0.",
  "fix_evidence": "run.log (guard mode) + fix.diff (patch --dry-run verified against the unmodified sys/dev/disk/sili/sili_cam.c)",
  "notes": "Device-absent, code-trace + model verified. Distinct from sili knowns DF-1338/1339/2517/2518 (SGE/NCQ bounds), DF-4027 (put_xfer of port-owned ccb - this is the complementary unchecked get_xfer), DF-1462/2519 (passthrough copy-paste).",
  "recommended_fix": "NULL-check every sili_ata_get_xfer() result in sili_cam.c (defer the probe with EBUSY at :289, break the renegotiation loop at :371, complete I/O ccbs with CAM_RESRC_UNAVAIL at :1026/:1420)."
}