# DF-5047 VERDICT — idad_dump fake success via discarded controller status

**status: untested (hardware-gated) | impact: none demonstrated (crash-dump integrity) | confidence: likely**

## Reproduced?

No. The trigger needs a physical Compaq SMART/IDA controller configured as
the dump device. Guest evidence (env.txt): `pciconf -l` shows no vendor
0x0e11 function, so `ida_pci_probe` never matches (ida_pci.c:193-210) and no
`idad` device exists (`ls /dev/idad*` -> NO_IDAD_DEVS). Untested = hardware
absent, not refuted.

## Why the finding is real (trace)

1. Dump chunk sizes are safe here: `si_iosize_max = min(MAXPHYS, 64*1024)`
   (ida_disk.c:281) -> `di.maxiosize` (sys/kern/subr_disk.c:934) ->
   `cb_dumpdata` clamps chunks to `min(MAXPHYS, maxiosize)` = 64KB
   (sys/platform/pc64/x86_64/dump_machdep.c:168-177), so
   `hwqcb->req.bcount = howmany(len, DEV_BSIZE) = 128` fits the u16 field
   (ida.c:411) and bus_dmamap_load stays within the MAXBSIZE tag
   (ida.c:209-213). **The math is fine; the status reporting is the bug.**
2. `idad_dump` clears IDA_INTERRUPTS and polls (ida_disk.c:202-208) ->
   `ida_command` -> `ida_wait` polling branch (ida.c:455-467): on completion
   it calls `ida_done(ida, qcb)` and returns 0. It never checks anything
   afterwards.
3. `ida_done` computes `error` from `req.error & HARD_ERROR|CMD_REJECTED`
   (ida.c:515-524) and, for `IDA_COMMAND` (which dump writes are — flags
   `DMA_DATA_OUT | IDA_COMMAND`, ida.c:350), only `wakeup(qcb)`
   (ida.c:526-528). The error bit dies there.
4. `ida_command` returns `error` = whatever `ida_wait` said = 0
   (ida.c:355-361), with the author's own admission at :358-359
   (`/* XXX should have status returned here? */`).
5. `idad_dump` returns that 0 to `dev_ddump` (sys/kern/kern_device.c:423-446)
   -> `cb_dumpdata` treats it as success and advances (dump_machdep.c:188-192);
   the run ends with "Dump complete" (:363-364).

A CMD_WRITE rejected by the controller therefore produces a "successful"
dump with missing/garbage pages — the same integrity failure class as
DF-5027 (ips). Because the affected writes are crash-dump pages only (the
normal data path goes through qcb->bio and sets B_ERROR correctly at
ida.c:530-532), disk data written by user I/O is unaffected.

## Why Low

- Hardware-gated (1999-era Compaq arrays; QEMU cannot emulate one).
- Only exercised during a panic with a failing controller.
- Impact is loss of forensic evidence (silent bad dump), not memory
  corruption or privilege.

## Fix assessment

fix.diff records `qcb->error = EIO` in `ida_done` before the command wakeup
and propagates it from `ida_command` after `ida_wait` succeeds. For the dump
path (polling, crit-held, single-CPU post-panic) this is race-free and
complete. For the general interrupt-path there remains a narrow
qcb-reuse race (qcb goes back on the free list at ida.c:536 before the
waiter reads qcb->error) — noted in the diff comment; a full fix would hold
the qcb until the status is consumed. fix_status=not_testable: no IDA
hardware on the guest to build and validate a patched kernel.

## Bottom line

Real DF-5027-family defect, code-certain (the driver itself marks the
missing status return with XXX), untestable here solely for lack of the
hardware.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
