DF-4027 / verdict.json
{ "finding_id": "DF-4027", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Code-trace proven; not live-reproducible on the audit guest because no sili(4) HBA exists there (device-absent, not a false positive): sili_poll() returns the non-terminal ATA_S_ONCHIP to its caller whenever sili_core_timeout() defers the timeout (other commands still active on the port, sili.c:2505-2511 -> 1359), and every poll caller in sili_cam.c then does sili_ata_put_xfer() on the still port-owned ccb (sili_cam.c:318/548/570/595/668). The recycled ccb is re-issued on the same slot (double ap_active accounting), and the stale completion in sili_port_reinit (sili.c:403-413) unloads the NEW commands active dmamap and runs complete() - for CAM commands sili_ata_complete_disk_rw -> xpt_done on the new requests CAM ccb (double CAM completion / UAF), or trips KKASSERT(ap_active_cnt==0) on INVARIANTS kernels.", "exploit_chain": "crafted SATA device / PM target stalls a polled probe command (IDENTIFY/SET_FEATURES, 1000ms) while another command is active on the same port -> deferred timeout returns ATA_S_ONCHIP -> sili_cam put_xfer of port-owned ccb -> ccb+slot reused by next command -> port drain completes stale request -> bus_dmamap_unload of the active new transfer (DMA writeback onto freed/reused memory) + double xpt_done on a live CAM ccb -> kernel memory corruption in the CAM/SILI boundary (or INVARIANTS panic via ap_active_cnt underflow at sili_port_hardstop).", "evidence": "VERDICT.md (full line-verified trace incl. every poll call site and the two completion sinks); sili_model.c prints the interleaving; no hardware on guest so no run.log - status reflects device absence, not refutation", "kernel_refs": [ "sys/dev/disk/sili/sili.c:1311-1360", "sys/dev/disk/sili/sili.c:2440-2443", "sys/dev/disk/sili/sili.c:2488-2511", "sys/dev/disk/sili/sili.c:2002-2030", "sys/dev/disk/sili/sili.c:403-413", "sys/dev/disk/sili/sili.c:2392-2419", "sys/dev/disk/sili/sili.c:1532-1536", "sys/dev/disk/sili/sili.c:1113", "sys/dev/disk/sili/sili_cam.c:315-321", "sys/dev/disk/sili/sili_cam.c:543-595", "sys/dev/disk/sili/sili_cam.c:661-668", "sys/dev/disk/sili/sili_cam.c:1331-1334", "sys/dev/disk/sili/sili_cam.c:1638" ], "poc_changes": "No seed PoC existed; sili_model.c is a userspace model of the kernel interleaving (hardware trigger not available on the guest).", "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 -O2 -o sili_model sili_model.c && ./sili_model", "run_cmd": "./sili_model", "code_hash": "8c331623405801d7138838d968a6a3b897cf616525784e9f80f68fee256d3bdb", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "not_testable: guest has no sili HBA; proposed guard in VERDICT.md (do not sili_ata_put_xfer on non-terminal ATA_S_ONCHIP/ATA_S_PENDING poll returns; mirror the CAM-polled path which already leaves the ccb to the port)", "fix_evidence": "VERDICT.md Fix section", "notes": "Device-absent, code-trace verified. Same crafted-disk threat model as DF-3690..3696; mechanism distinct from DF-4014 (free-on-timeout) and from the sili knowns DF-1338/1339/2517/2518 (SGE/NCQ-tag bounds).", "recommended_fix": "In sili_cam.c poll error paths, only sili_ata_put_xfer() when xa->state is terminal (not ATA_S_ONCHIP/ATA_S_PENDING); the port retains ownership of deferred cbs and completes them via sili_port_reinit()." } |