# DF-4355 — VERDICT

**Status:** `untested` (hardware-gated) · **Source-level confidence:** certain · **Expected on real hardware:** unrecoverable system hang (interrupt-context / serializer-held infinite spin).

## Root cause (path:line)

The SMC91xx driver waits for the on-chip MMU engine and the RX FIFO with **completely unbounded busy-loops**:

1. `sys/dev/netif/sn/if_sn.c:275-276` — `sninit()`: `while (inw(BASE + MMU_CMD_REG_W) & MMUCR_BUSY);` after `MMUCR_RESET`. Runs under the ifnet serializer (SIOCSIFFLAGS → sninit, if_sn.c:1090; watchdog → sn_intr → EPH path → sninit, if_sn.c:924-927).
2. `sys/dev/netif/sn/if_sn.c:641-642` — `snresume()` wrong-size-allocation release path.
3. `sys/dev/netif/sn/if_sn.c:871-872` — `sn_intr()` TX-error path before `MMUCR_FREEPKT`. **Hard interrupt context.**
4. `sys/dev/netif/sn/if_sn.c:1056-1057` — `snread()` per-packet release before `MMUCR_RELEASE`. **Hard interrupt context**, inside the `read_another` loop, so it executes for every received frame.

`MMUCR_BUSY` is `0x0001` (`sys/dev/netif/sn/if_snreg.h:238`). On a card that is ejected mid-operation, pccard bus reads float (conventionally 0xFFFF), so `inw() & 0x0001` is persistently true: all four sites spin forever. Sites 3-4 spin in a hard interrupt handler holding the ifnet serializer — nothing else on the system can make progress; the serial-console softclock path that would normally print a hang watchdog is starved of the interrupt → total hang, power-cycle required. The `sn_pccard_detach()` path cannot quiesce the driver because it needs the same serializer (see known DF-2186, `sys/dev/netif/sn/if_sn_pccard.c:110-121`) — detach itself deadlocks against the spinner.

Additional device-driven no-exit loops in the same fault model:

- `sys/dev/netif/sn/if_sn.c:446-450` — `ARR_FAILED` → `ifq_prepend()` → `goto startagain` (354): with a card whose MMU allocation fails immediately and forever, `snstart()` re-dequeues the same mbuf and re-issues the allocation in a tight loop at serializer context.
- `sys/dev/netif/sn/if_sn.c:1063-1067` — `read_another`: no cap on the number of packets drained per interrupt; a card that keeps `FIFO_REMPTY` (0x8000) clear pins the RX interrupt handler indefinitely.

Contrast: the allocation wait at if_sn.c:415-419 **is** bounded (`MEMORY_WAIT_TIME` = 1000, if_snreg.h:60) — the unbounded sites are an oversight, not a style choice.

## Threat model

Local attacker with **physical access** to a machine using an SMC91xx PCMCIA/ISA NIC (or a failing card): eject the card while the interface is up and transmitting/receiving → hang. There is no unprivileged-software-only trigger: the loops only spin when the hardware misbehaves or vanishes. Severity **Low** (hardware-gated DoS), confidence certain at source level.

## Why untested on this guest

Same hardware gate as DF-4354: the QEMU guest has no PCMCIA slot/SMC91xx chip; `if_sn` is an `optional sn` module with a pccard-only front-end (`sys/conf/files:1247`, `sys/dev/netif/sn/if_sn_pccard.c:126-133`). Guest inventory captured in `env.txt` (only `vtnet0`/`lo0`). No guest-side reproduction is possible without emulating the card; classification is untested-with-source-certainty rather than not-reproduced (nothing was executed and failed — the path simply cannot exist on this machine).

## Fix validation

`fix_status: not_testable` (same hardware gate). The `fix.diff` pattern (bounded `MEMORY_WAIT_TIME*1000` spin with `DELAY(1)` and bail-out leaving the interface for the watchdog) is the same approach the driver already uses at if_sn.c:415-419; applying it at the four MMU sites plus iteration caps on the FIFO/ARR loops removes every unbounded spin. By inspection the patched loops always terminate within ~1s per wait on both healthy and vanished hardware.

## Kernel references

- sys/dev/netif/sn/if_sn.c:275-276 (sninit MMU reset wait — unbounded)
- sys/dev/netif/sn/if_sn.c:641-642 (snresume wait — unbounded)
- sys/dev/netif/sn/if_sn.c:871-872 (sn_intr TX-error wait — unbounded, hard IRQ)
- sys/dev/netif/sn/if_sn.c:1056-1057 (snread release wait — unbounded, hard IRQ, per packet)
- sys/dev/netif/sn/if_sn.c:446-450 (ARR_FAILED startagain retry loop)
- sys/dev/netif/sn/if_sn.c:1063-1067 (read_another FIFO walk, no cap)
- sys/dev/netif/sn/if_sn.c:415-419 (the bounded counter-example)
- sys/dev/netif/sn/if_snreg.h:238 (MMUCR_BUSY 0x0001), :60 (MEMORY_WAIT_TIME 1000), :263 (FIFO_REMPTY 0x8000)

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