{
  "finding_id": "DF-5061",
  "status": "reproduced",
  "verdict": "ida_v4_done()s empty-reply-FIFO sentinel completed == -1 (ida_pci.c:107) is dead code on LP64: completed is bus_addr_t (uint64_t, bus_dma.h:36) assigned from bus_space_read_4() (u_int32_t, bus_dma.h:130), so the 42xx empty-FIFO value 0xFFFFFFFF zero-extends and never matches (bus_addr_t)-1. ida_wait()s poll loop (ida.c:457, the path every ida_command() takes during attach with interrupts disabled) and ida_intr()s drain loop (ida.c:482) then consume the empty FIFO as completion 0xFFFFFFFF; idahwqcbptov() (ida.c:140-148) computes hwqcbs + (0xFFFFFFFC - hwqcb_busaddr) == DMAP+0xFFFFFFFC and dereferences hwqcb->qcb. Verified on the guest with verbatim driver code and a mock register file returning 0xFFFFFFFF: Fatal trap 12, supervisor read data, page not present, faulting instruction movq 0x110(%rax,%rdx,1),%r13 (the hwqcb->qcb load), fault VA == hwqcbs + (0xFFFFFFFC - busaddr) + 0x110 exactly. Driver ships in GENERIC (X86_64_GENERIC:132) so v4 boards panic during boot attach; >=4GB hosts instead read mapped garbage and spin forever in the ISR. Read primitive only (no write/copyout) and hardware-gated (Compaq SMART-2/4x00 PCI IDs) => kernel DoS, Low severity. Fixed variant (masked compare) returns 0, performs no empty-FIFO confirm-write, no fault; patched driver rebuilds clean with -Werror.",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "exploit_chain": "Compaq 42xx-class board present (PCI 0x0e11:0xae10/0x4040x0E11 subclass) -> GENERIC kernel ida_pci_attach at boot -> ida_attach() disables interrupts -> first ida_command(CMD_GET_CTRL_INFO) -> ida_wait() polls ida_v4_done() on an empty reply FIFO -> dead sentinel returns 0xFFFFFFFF as a completion (+ bogus confirm read write to R_42XX_REPLY on the empty FIFO) -> idahwqcbptov(0xFFFFFFFC) -> deref at DMAP+0xFFFFFFFC -> page fault panic (<4GB RAM) or mapped-garbage qcb -> qcb->state != QCB_ACTIVE -> ida_intr spins forever (>=4GB RAM). No write primitive, no data returned to userspace: DoS ceiling.",
  "evidence": "panic.txt: Fatal trap 12 ... fault virtual address = 0xfffff801625a310c ... supervisor read data, page not present ... Stopped at df5061_fire_sysctl+0xb5: movq 0x110(%rax,%rdx,1),%r13 with 0xfffff801625a310c == hwqcbs(0xfffff80118498000) + (0xFFFFFFFC - hwqcb_busaddr(0xb5ef5000)) + 0x110 (the verbatim idahwqcbptov hwqcb->qcb load). panic.firstboot.txt: sentinel-DEAD prints + ida_v4_done() = 0x00000000ffffffff (empty FIFO reported as a completion!) + empty-FIFO confirm-write side effect + panic. run.log/fix_run.log: fixed variant returns 0, register untouched, no fault. fix_build.log: patched ida.ko builds clean (-Werror). build.log: harness KLD build. env.txt/hwgate.txt: guest uname, 3.96GB RAM, no Compaq PCI device (mocked register file runs the drivers own kernel-side code verbatim).",
  "kernel_refs": [
    "sys/dev/raid/ida/ida_pci.c:101",
    "sys/dev/raid/ida/ida_pci.c:107",
    "sys/dev/raid/ida/ida_pci.c:109",
    "sys/cpu/x86_64/include/bus_dma.h:36",
    "sys/cpu/x86_64/include/bus_dma.h:130",
    "sys/dev/raid/ida/idavar.h:40",
    "sys/dev/raid/ida/ida.c:457",
    "sys/dev/raid/ida/ida.c:463",
    "sys/dev/raid/ida/ida.c:482",
    "sys/dev/raid/ida/ida.c:140",
    "sys/dev/raid/ida/ida.c:146"
  ],
  "poc_changes": "No seed PoC existed (pass-2 new finding). Authored harness KLD embedding VERBATIM copies of ida_v4_done() (ida_pci.c:101-111) and idahwqcbptov() (ida.c:140-148) against a mock 32-bit MMIO register file (R_42XX_REPLY=0xFFFFFFFF, the documented empty-FIFO value). kmod.mk quirks handled: interface headers via SRCS+=device_if.h bus_if.h; -I must ride COPTS because kmod.mk:98 overwrites CFLAGS. A survivable probe mode was added but even it faults - idahwqcbptov() must dereference hwqcb->qcb to return at all, which is itself proof the driver cannot compute the qcb without touching wild memory.",
  "attempts": 4,
  "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": 1800,
  "guest_dirty": 1,
  "build_cmd": "sh build.sh  (cd /tmp/df5061 && make SYSDIR=/usr/src/sys)",
  "run_cmd": "kldload /tmp/df5061/df5061.ko; sysctl hw.df5061_mode=2; sysctl hw.df5061_fire=1",
  "code_hash": "fcea53751b01e5384abf7c942ab1aaa0cf2aa22a2f7865ef8bce4c425b27dd65",
  "notes": "Impact ceiling honestly characterized: wild READ feeding a compare; no kernel-memory write or copyout, so privesc is not on the table - DoS (boot panic <4GB / ISR hang >=4GB). The driver is compiled into X86_64_GENERIC (line 132 device ida), so no kldload is needed on real hardware - attach happens at boot. v3 boards (SMART-2/P etc.) use ida_v3_done() which has no sentinel at all and was not modified. Guest was reset (with-src) after the panics; /usr/src inside the guest carries the fix.diff validation build only after the final reset (see fix fields).",
  "recommended_fix": "Mask the empty-FIFO sentinel to the 32-bit register width: if (completed == (bus_addr_t)0xffffffffU) return (0);",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff applied inside the guests /usr/src; the real ida driver (ida.c+ida_pci.c+ida_disk.c) rebuilt clean as ida.ko with -Werror (fix_build.log). The fixed logic variant ((uint32_t)completed == 0xffffffff) re-run on the guest returns 0 for the empty FIFO, performs no confirm read write on it, and faults nothing (run.log, fix_run.log) - the previously-observed Fatal trap 12 does not occur. git apply --check passes against the pristine sys/ tree.",
  "fix_evidence": "fix.diff; fix_build.log (ida.ko link line, -Werror clean); fix_run.log (fixed variant: ida_v4_done_fixed() = 0x0000000000000000 ... R_5061 untouched: 0xffffffff ... DF-5061: unloaded); panic.txt vs panic.firstboot.txt (baseline traps absent under the fix)."
}