# DF-4888 — iir_pci_attach error-path unwind: BAR resource never released; bus_setup_intr failure leaves XPT sims + /dev/iirN + pools live with no interrupt

**Status: untested (hardware-gated — no Intel SRC / ICP RAID controller on the audit guest, code-certain by inspection).**
Severity: Low. Class: improper resource shutdown / error-path lifetime (CWE-404).

## Root cause (two distinct unwinding gaps in `sys/dev/raid/iir/iir_pci.c`)

### (a) The DPMEM BAR resource `io` is never released on ANY attach failure
`iir_pci_attach` allocates BAR0 at iir_pci.c:186-192 (`rid = PCI_DPMEM; io = bus_alloc_resource_any(...)`),
then **overwrites `rid` to 0** for the IRQ allocation (iir_pci.c:195-197). Every failure path after that
(DPMEM magic mismatch :225-231, DEINIT timeout :253-261, protocol mismatch :267-271, init-error timeout
:290-298, dma tag create :314-323, `iir_init` failure :326-330, `bus_setup_intr` failure :336-341) jumps to
`err:`, which releases only `irq`. The `io` release is **commented out** — and would be wrong anyway,
because `rid` no longer holds the memory rid:

```c
346: err:
347:     if (irq)
348:         bus_release_resource( dev, SYS_RES_IRQ, 0, irq );
349: /*
350:     if (io)
351:         bus_release_resource( dev, SYS_RES_MEMORY, rid, io );
352: */
353:     return (error);
```

Because attach failed, newbus will never call a detach (the driver has none), so the rman resource for
BAR0 leaks permanently. Each failed re-probe (`devctl rescan`, kldload after flaky-card failure, hot-plug
flap) leaks another one — rman pool exhaustion eventually blocks other devices on the bus from mapping
their BARs.

### (b) `bus_setup_intr` failure skips ALL higher-level teardown
`iir_init(gdt)` (iir_pci.c:326) and `iir_attach(gdt)` (iir_pci.c:333) have already, by the time
`bus_setup_intr` runs at iir_pci.c:336:

* inserted `gdt` into the global `gdt_softcs` TAILQ (iir.c:199),
* created DMA tags, the ccb pool and `GDT_MAXCMDS` dmamaps (iir.c:202-268),
* created the control device `/dev/iirN` (iir.c:272),
* registered `GDT_MAXBUS` CAM SIMs with the XPT and wildcard paths (iir.c:490-511),
* registered a `shutdown_post_sync` handler (iir.c:514).

When `bus_setup_intr` fails (iir_pci.c:336-341) the code jumps to `err:` releasing **only** the IRQ —
`iir_free()` is never called, the SIMs are never deregistered. Result on a live system:

1. Permanent leak of `sc_parent_dmat`, `sc_buffer_dmat`, `sc_gcscratch_dmat`, `sc_gcscratch`,
   `sc_gccbs`, and the `/dev/iirN` cdev.
2. The XPT-registered SIMs are immediately used by CAM's bus scan; `iir_action` queues commands to a
   board whose **completions can never be delivered** (no interrupt handler, and `iir_timeout` is an
   empty handler — DF-4176). All scanned CCBs hang forever, wedging the CAM rescan thread.
3. The `shutdown_post_sync` handler stays registered against a controller that was never enabled
   (`gdt_pci_enable_intr` at iir_pci.c:343 is skipped), leaving a shutdown-time hazard.

Contrast: the author *did* unwind `iir_init` on its own failure (iir_pci.c:326-330 calls `iir_free`),
proving the omission at :336-341 is an oversight, not a design decision.

## Threat model
Requires the Intel SRCZCRX / ICP vortex RAID PCI hardware (vendor 0x8086 dev 0x0600, or 0x1119
0x0100-0x02ff/0x0300 — iir_pci.c:160-171) to be present AND attach to fail at the specific late stage
(IRQ registration failure / flaky DPMEM). No unprivileged-user trigger; impact is resource exhaustion
and I/O wedge on the host (admin/hardware-triggered DoS). Same trigger surface and severity band as the
sibling iir findings DF-4173/DF-4175/DF-4176.

## Fix
See `fix.diff` (saves the memory rid and releases `io` on every error path; on `bus_setup_intr` failure
deregisters the XPT paths/SIMs that `iir_attach` created, drops the shutdown handler, and calls
`iir_free()`).

## 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.
