# DF-4354 — VERDICT

**Status:** `untested` (hardware-gated) · **Source-level confidence:** certain · **Expected on real hardware:** kernel NULL-deref panic at device attach; collateral stray writes to ISA DMA-controller ports.

## Root cause (path:line)

1. `sn_attach()` at `sys/dev/netif/sn/if_sn.c:164` invokes `sn_activate(dev)` **without checking the return value**. Compare `sn_probe()` at if_sn.c:1236-1237, which *does* check it (`if ((err = sn_activate(dev)) != 0) return err;`).
2. `sn_activate()` (if_sn.c:1166-1193) can fail after either resource allocation:
   - `bus_alloc_resource(... SYS_RES_IOPORT ...)` failure → returns `ENOMEM` at if_sn.c:1177 with `sc->port_res == NULL`;
   - `bus_alloc_resource_any(... SYS_RES_IRQ ...)` failure → returns `ENOMEM` at if_sn.c:1188 (port already released by `sn_deactivate`), `sc->irq_res == NULL`.
   In both cases `sc->sn_io_addr` is never written (if_sn.c:1191 is only reached on success). The newbus softc is zero-allocated (`M_ZERO` in `devclass_alloc_device`), so `BASE` macro (`sc->sn_io_addr`, `sys/dev/netif/sn/if_snreg.h:400`) evaluates to **0**.
3. Attach continues:
   - if_sn.c:173 `SMC_SELECT_BANK(3)` → `outw(0x0E, 3)` — port 0x0E is the ISA DMA controller (8237) write-request/chain-mask register;
   - if_sn.c:174 `rev = inw(0x0A)` — reads DMA ch2 word count as "chip revision"; the value then feeds `chip_ids[(rev>>4)&0xF]` (the DF-1552 OOB-print issue, now reachable at attach with pure garbage);
   - if_sn.c:179 `i = inw(0x00)` — DMA ch0 address register;
   - if_sn.c:182-189 (when `sc->pccard_enaddr`) `outw(0x04, w)`, `outw(0x06, w)`, `outw(0x08, w)` — **writes the MAC address into the DMA ch1/ch2 address registers**;
   - any later `sninit()` (if_sn.c:268 `outw(BASE+CONFIG_REG_W, flags)` = `outw(0x00, flags)`, if_sn.c:248 `outw(BASE+RECV_CONTROL_REG_W, RCR_SOFTRESET)`, etc.) scribbles further over the DMA controller / PIC-adjacent low ports.
4. **The deterministic crash:** if_sn.c:216 `ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->irq_res));` with `sc->irq_res == NULL`. `rman_get_cpuid(r)` expands to `((r)->r_rm->rm_cpuid)` (`sys/sys/rman.h:157`) — an immediate NULL-pointer dereference in kernel mode during `DEVICE_ATTACH`, before the error path at if_sn.c:221-224 could ever run.

## Why it is a real (if narrow) finding

- It is an **error-path asymmetry** of exactly the kind pass 2 hunts: the probe path checks the same call, the attach path does not.
- Impact ceiling on real hardware: kernel panic at boot/card-insertion time (availability), plus undefined low-port I/O side effects on the ISA DMA controller (system instability). Reachability requires a resource-allocation failure at attach (CIS resource conflict / IRQ steal in the probe→attach window) — plausible on pccard, rare otherwise.
- Not remotely triggerable, not an info leak, not memory corruption. Severity **Low**.

## Why untested on this guest

- `if_sn.c` is compiled only as the `optional sn` module (`sys/conf/files:1247`); its only front-end is pccard (`sys/dev/netif/sn/if_sn_pccard.c:126-133`, `DEVMETHOD(device_attach, sn_pccard_attach)` → `sn_attach`).
- The QEMU guest (see `env.txt`) exposes only `vtnet0`/`lo0`, has no PCMCIA slot and no SMC 91xx chip; therefore the attach path cannot execute. No amount of guest setup short of emulating PCMCIA + an SMC91C9x card can reach the bug — this is a genuine hardware gate, not a missing-setup case.

## Fix validation

`fix_status: not_testable` for the same hardware reason. The one-line fix (check the return of `sn_activate()` in `sn_attach` and propagate the error) is contained in `fix.diff`; by inspection it makes the attach path return before any BASE-relative I/O and before the `rman_get_cpuid` call, mirroring the probe path at if_sn.c:1236-1237.

## Kernel references

- sys/dev/netif/sn/if_sn.c:164 (unchecked return)
- sys/dev/netif/sn/if_sn.c:173-188 (BASE=0 port I/O: 0x0E/0x0A/0x00/0x04-0x08 — ISA DMA controller range)
- sys/dev/netif/sn/if_sn.c:216 (rman_get_cpuid(NULL))
- sys/dev/netif/sn/if_sn.c:1170-1192 (failure modes of sn_activate)
- sys/sys/rman.h:157 (rman_get_cpuid double-deref expansion)
- sys/dev/netif/sn/if_snreg.h:400 (BASE == sc->sn_io_addr)
- sys/dev/netif/sn/if_sn.c:1236-1237 (probe path *does* check — the asymmetry)

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