# DF-3680 VERDICT — unvalidated TX-head index in cleanup loops

## Status: inconclusive on guest (no igb hardware) — source-certain

## Root cause (path:line)
`igb_txeof()` (`sys/dev/netif/igb/if_igb.c:2174-2217`):

```c
2174: igb_txeof(struct igb_tx_ring *txr, int hdr)
...
2181: first = txr->next_to_clean;
2182: if (first == hdr)
2183:         return;
2185: avail = txr->tx_avail;
2186: while (first != hdr) {              /* hdr NIC-controlled, unvalidated */
2189:         KKASSERT(avail < txr->num_tx_desc);
2190:         ++avail;
...
2195:         if (++first == txr->num_tx_desc)
2196:                 first = 0;
2197: }
```

`hdr` comes verbatim from the DMA'd TX-head write-back buffer at every call
site: `igb_npoll_tx` `:3361`, `igb_intr` `:3454`, `igb_intr_shared` `:3516`,
`igb_msix_tx` `:4737`, `igb_msix_rxtx` `:4938` — all `igb_tx_intr(txr,
*(txr->tx_hdr))`. `tx_hdr` is `uint32_t *` (`if_igb.h:250`), written by the
NIC in head write-back mode (`igb_init_tx_unit:2072-2075` configures
`TDWBAH/TDWBAL | E1000_TX_HEAD_WB_ENABLE`). No call site masks or range-checks
the value; `igb_txgc()` (`:2220-2251`) has the identical loop against the
`TDH` register read (`:2230`).

## Consequence arithmetic
`first` iterates modulo `num_tx_desc` (256..4096). For `hdr` ∉
[0, num_tx_desc) — including values ≥ 2^31 which become negative `int` — the
loop never terminates. Each iteration increments `avail`; after
(`num_tx_desc - tx_avail`) iterations `avail == num_tx_desc` → `KKASSERT` at
`:2189` panics INVARIANTS kernels; production kernels spin forever holding
`txr->tx_serialize` inside the ISR → the serializer is never released, that
CPU wedges, and the interrupt is re-armed (EIMS write) in a tight storm.
Mbufs are freed on the first pass only (`txbuf->m_head` set NULL by
`igb_free_txbuf`), so the tail of the loop is a pure spin.

## Threat model
The write-back value is device-controlled. Legit hardware always writes
valid indices; the exposure is device fault / erratum / DMA corruption /
malicious-PCIe (or VF-assigned) scenarios — identical premise to DF-3668
(ix), filed Low/certain. Note the driver itself documents observed spurious
interrupts on these LOMs (`if_igb.c:723-727`), and after `igb_stop()` +
NIC reset a stale/garbage write-back can be consumed by a spurious interrupt
(`igb_init` re-zeroes `*tx_hdr` only at init, `:2019`).

## Why not reproduced on the guest
No igb hardware: `ifconfig -a` shows only `vtnet0`/`lo0`; driver compiled
into the kernel; `/boot/kernel/if_igb.ko` present. `igb_attach()` never runs,
so no TX ring or write-back buffer exists. See `run.log`.

## Fix
Range-check `hdr` before the loops in both `igb_txeof()` and `igb_txgc()`
(`fix.diff`). Not hardware-testable: `fix_status = not_testable`.

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