# DF-5153 VERDICT — dpt_pci.c setup_intr-failure incomplete unwind

**Status: untested** (hardware-gated). **Impact: none demonstrable on the
audit guest** (no DPT controller present — verified, `env.txt`).
**Confidence: certain** that the defect exists as described (line-proven).
**Fix: authored, not kernel-validated** (`fix.diff`; baseline behavior
cannot be reproduced without the HBA, so fix validation is `not_testable`).

## 1. Root cause (line-certain)

* `sys/dev/raid/dpt/dpt_pci.c:151` — `dpt_init(dpt)` succeeds (DMA tags at
  dpt_scsi.c:1235/1356/1370, CCB array at :1385, sg maps at :1254).
* `sys/dev/raid/dpt/dpt_pci.c:159` — `dpt_attach(dpt)` registers up to 3
  SIMs + wildcard paths with XPT and the `shutdown_post_sync` handler
  (dpt_scsi.c:1466-1488); return value (channel count) is ignored by the
  glue — harmless here since >0 channels means live registrations either way.
* `sys/dev/raid/dpt/dpt_pci.c:163-169` — `bus_setup_intr` failure jumps to
  `bad:` having undone **nothing** of the above.
* `sys/dev/raid/dpt/dpt_pci.c:173-179` — `bad:` releases only io/irq. The
  io release passes rid 0 for a resource allocated at rid
  `PCIR_MAPS`(=0x10)/`PCIR_MAPS+4` → `pci_release_resource`'
  `resource_list_delete(rl, type, rid)` lookup misses → EINVAL no-op → the
  io leaks (this half is **DF-2151**, known). The irq release at :176-177
  uses rid 0, which matches the allocation rid at :103-105 → genuinely
  released while the device keeps its registers programmed (busmaster was
  forced on at :113-114).
* `sys/kern/subr_bus.c:3328-3333` — `bus_release_resource` is a pure
  rid-keyed dispatch, confirming the asymmetry.

## 2. What stays alive (the defect)

| Object | Created at | Released on failure? |
|---|---|---|
| XPT buses/sims | dpt_scsi.c:1466-1473 | **never** (phantom SIM) |
| CAM wildcard paths | dpt_scsi.c:1475-1482 | **never** |
| `shutdown_post_sync` handler (tag discarded) | dpt_scsi.c:1487-1488 | **never** |
| softc on global `dpt_softcs` | dpt_scsi.c:1165 | **never** |
| CCB DMA memory + 3 DMA tags | dpt_init | **never** (`dpt_free` not called) |
| io resource | dpt_pci.c:88/94 | no-op leak (DF-2151) |
| irq resource | dpt_pci.c:104 | released (correct rid) — while the card can still assert it |

## 3. Reachability / threat model

Entry requires `dpt_pci_probe` to match PCI 0x1044:0xa400 (dpt_pci.c:61-66)
— real DPT SmartRAID hardware — **and** `bus_setup_intr` to fail (interrupt
vector exhaustion, MSI/MSI-X setup failure on the platform). Both are
boot/kldload-time conditions. **No unprivileged local user trigger exists**;
on hardware without the card the driver never attaches (verified on the
guest: `pciconf -l` shows no 0x1044 device). uid=0 escalation is not
applicable: no user-controlled grooming window, no kernel-heap primitive —
the residual primitives are (a) a CAM-reachable bus_space handle whose rman
record was released/re-allocatable, (b) an irq released under a
busmaster-enabled device, (c) permanent leaks, (d) never-completing CAM
commands (boot hang). Ceiling on real hardware: cross-device PIO/MMIO
corruption and boot-time DoS.

## 4. Why untested (honest classification)

* Guest has no DPT HBA (`env.txt`) → `dpt_pci_attach` unreachable, and no
  userland program can reach any part of this path even with one present.
* Unlike DF-5141 (mlx double-free — reproduced via KLD harness driving the
  real `mlx_free()` twice), the consequence here is *logical* (CAM/rman
  lifetime), not allocator-detectable: a harness that fabricates a softc and
  calls `xpt_bus_register` + `bus_release_resource` would only demonstrate
  that CAM keeps a sim whose resource was released — the code's own text —
  without adding evidentiary weight. Recorded as analysis-verified instead.

## 5. Fix

`fix.diff` (dpt_pci.c + dpt.h + dpt_scsi.c): reverse-order teardown on the
failure branch — free paths, deregister buses, free sims, deregister the
shutdown handler via a tag now stored in the softc, `crit_enter`;
`dpt_free(dpt)`; `crit_exit()`; `bus_dma_tag_destroy(dpt->parent_dmat)`
(covers DF-5154 on this path); and the io rid correction in `bad:` (hunk
shared with DF-2151's fix). Not kernel-build-validated (no target hardware;
fix validation `not_testable`).

## 6. Kernel references

sys/dev/raid/dpt/dpt_pci.c:159, :163-169, :173-179, :88-94, :103-105, :113-114;
sys/dev/raid/dpt/dpt_scsi.c:1165, :1235, :1356, :1370, :1385, :1466-1488, :1717-1733;
sys/kern/subr_bus.c:3328-3333.

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