# DF-5042 — VERDICT

**Verdict:** REPRODUCED (runtime, verbatim driver code, no hardware required for the replay)
**Class:** resource leak / improper error handling (CWE-404/755)
**Impact ceiling:** none (kernel kmem leak per failed attach; unbounded across attach retries)
**Confidence:** certain

## Reproduction

The guest has **no AdvanSys HBA** (no vendor 0x10CD device; `pciconf -lv`),
and `adv_pci.c` is not even built on X86_64_GENERIC (`device adv0 at isa`
registers a `pci/adv` module id but no hardware ever probes).  The finding is
therefore hardware-gated for the *natural* trigger, but the failure unwinds
themselves were replayed **at runtime on the guest** by compiling the four
driver translation units verbatim into a kld and driving the real
`adv_pci_attach()` with a scripted chip (see README.md).  This is the same
technique the DF-4964 pack used for sili.

Two scenarios, both observed in `run.log` (fresh clean-source guest,
kernel `6.5-DEVELOPMENT #0 Thu Jul 2 06:02:54 2026`):

* **mode INITFAIL** — the *real* `adv_init()` runs against the scripted chip
  (signature present, `CHIP_STATUS` never sets `ADV_CSW_HALTED`), fails
  exactly at advansys.c:794-798 ("adv0: Unable to halt adapter.
  Initializationfailed"), and the adv_pci.c:260-264 unwind executes.
  Observation: `bus_dma_tag_destroy` calls for the **parent_dmat: 0** —
  `adv_free(adv)` ran `switch(1)` which enters at `case 1` (kfree
  ccb_infos — NULL) and never reaches `case 2` (destroy parent_dmat).
  `*** DF-5042 LEAK PROVEN ***`.

* **mode IRQFAIL** — `fk_adv_init` scripts success so attach reaches the IRQ
  stage; `bus_alloc_resource(SYS_RES_IRQ)` succeeds (fake resource),
  `bus_setup_intr` is scripted to fail; the adv_pci.c:289-294 unwind
  executes.  Observations: parent_dmat destroy **0** (DF-5042) **and**
  `bus_release_resource` for the IRQ resource **0** (DF-5043, filed
  separately); only the IOPORT resource is released.

## Mechanism (source-confirmed)

* adv_pci.c:184 creates `adv->parent_dmat`; adv_pci.c:202 then does
  `adv->init_level++` → init_level == **1**.
* `adv_free()` (advansys.c:747-776) is a fall-through switch where
  **case 1 = kfree(ccb_infos)** and **case 2 = bus_dma_tag_destroy(parent_dmat)**;
  the tiers 2..6 belong to `adv_attach()`'s own creations
  (advansys.c:1298,1339,1352,1360,1368).  With init_level == 1 the unwind
  starts at case 1 and skips case 2 — parent_dmat is never destroyed.
* The two overrun-allocation failure paths already work around exactly this
  by destroying `adv->parent_dmat` manually (adv_pci.c:212, adv_pci.c:222) —
  proof of intent — but the `adv_init()`-failure path (adv_pci.c:260-264)
  and the IRQ-setup-failure path (adv_pci.c:289-294) lack the manual destroy.
* Every failed attach therefore leaks one `bus_dma_tag_t` (plus, on the IRQ
  path, the active IRQ resource — DF-5043).  `device_doattach()`
  (sys/kern/subr_bus.c:2115-2124) drops the driver on attach failure without
  running any detach, so nothing else ever releases the tag; hotplug/rescan
  retries accumulate the leak.

## Fix validation (runtime A/B, no kernel rebuild needed)

`fix.diff` adds the missing explicit `bus_dma_tag_destroy(adv->parent_dmat)`
(and, on the IRQ path, `bus_release_resource(SYS_RES_IRQ)` — the DF-5043
half) to both unwinds, mirroring the file's own overrun-path idiom.
Rebuilding the kld against the patched `adv_pci.c` and replaying both modes
(`run.2.log`):

```
DF5042: bus_dma_tag_destroy: parent=1 overrun=0
DF5042: bus_release_resource: IOPORT=1 IRQ=1
DF5042: unwind clean (fix effective?)
```

Baseline leaks → patched clean, same driver code otherwise.  `fix.diff` is
`git apply --check` clean against the audited tree.

## Gating precondition (natural trigger)

AdvanSys ASC1200A/1200B/3000 PCI SCSI HBA (vendor 0x10CD) or VFIO-assigned
endpoint that probes, passes the signature check, and then fails
`adv_init()`/`bus_setup_intr()` — e.g. a wedged/missing chip behind a
decoding BAR, or IRQ exhaustion.  Root-relevant only as availability/kmem
hygiene; no escalation path (leaked tag contains no user data).

## Exploit chain

Not applicable — bounded-impact kmem leak per failed attach; no corruption,
no info disclosure. The leak primitive is a `bus_dma_tag_t` (+ embedded
segment array) per failed attach, repeatable with device re-probe loops.

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