# DF-4233 — txp_init() ignores txp_rxring_fill() failure; RX enabled over a stale buffer ring → firmware DMA into freed clusters + NULL deref

**File:** `sys/dev/netif/txp/if_txp.c` (pass 2)
**Severity:** High (memcorrupt bucket) — hardware-gated; precondition is a
transient `MCLGET(M_NOWAIT)` failure (kernel memory pressure) during
`ifconfig txp0 up`, then any inbound frame.

## Build / run — same guest probe as DF-4231 (`t4233.c`).

## The bug

`txp_init()` (`if_txp.c:1097-1144`):

1. `txp_stop()` at `:1110` → `txp_rxring_empty()` (`:1522` → `:1073-1094`)
   frees **all** 256 receive clusters and NULLs `sd->sd_mbuf`, but the
   DMA-shared `rb_paddrlo` ring entries keep pointing at the **freed**
   clusters, and `hv_rx_buf_write_idx` keeps its stale value ("buffers
   available").
2. `txp_rxring_fill(sc)` at `:1127` — **return value ignored**. On the first
   `MGETHDR`/`MCLGET(M_NOWAIT)` failure it returns `ENOBUFS` (`:1051`,
   `:1056`) after refilling only a prefix; `hv_rx_buf_write_idx` is updated
   only on **success** (`:1066-1067`), so the firmware still believes the
   old (stale) buffer count.
3. `TXP_CMD_TX_ENABLE`/`TXP_CMD_RX_ENABLE` are issued anyway (`:1129-1130`)
   and the interface is marked `IFF_RUNNING`.

When a frame then arrives for a stale ring entry:
- the firmware DMAs the (attacker-supplied) frame into the **freed** mbuf
  cluster listed in `rb_paddrlo` — use-after-free **write** with attacker
  content into the mbuf cluster zone;
- on completion, `txp_rx_reclaim()` does `m = sd->sd_mbuf` (NULL for the
  unfilled prefix) then `m->m_pkthdr.len = ...` at `:676` → **NULL write /
  panic**.

## Fix

`fix.diff`: propagate the fill failure — bail out of `txp_init()` (leave the
interface down) instead of enabling RX over a half-filled, stale ring.
