# DF-3720 — Firmware-returned SRAM offsets used as kernel write pointers with no validation (hostile-device family); plus int16_t ring-mask truncation

## Vulnerability

`sys/dev/netif/mxge/if_mxge.c` repeatedly turns a **device-returned offset**
(`mxge_send_cmd` response `cmd.data0`) into a raw pointer into the mapped
SRAM BAR (`sc->sram`, size `sc->sram_size` :4290) and then **writes through
it**, with no range check anywhere:

| Locus | Command | Sink |
|---|---|---|
| `mxge_reset` :1207-1215 | `GET_INTR_COAL_DELAY_OFFSET` / `GET_IRQ_ACK_OFFSET` / `GET_IRQ_DEASSERT_OFFSET` | `*sc->intr_coal_delay_ptr = htobe32(...)` write :1222 and live sysctl write `mxge_change_intr_coal` :1339 (`*sc->intr_coal_delay_ptr = ...`); `irq_claim` stores :2717-2718/:2779-2780/:2853-2854 |
| `mxge_slice_open` :3255-3283 | `GET_SEND_OFFSET` / `GET_SMALL_RX_OFFSET` / `GET_BIG_RX_OFFSET` | `tx->lanai` / `rx_*->lanai` — descriptor rings written by `mxge_submit_req`/`mxge_submit_8rx` PIO (e.g. :1580, :2030-2036) |
| `mxge_open` :3351-3364 | `GET_RSS_TABLE_OFFSET` | 128-byte table write loop :3363-3364 |
| `mxge_open` :3373-3384 | `GET_RSS_KEY_OFFSET` | 16-byte key write loop :3382-3383 |

A hostile/compromised NIC (or one returning garbage after a fault) supplies
an offset ≥ `sram_size` and the kernel performs MMIO writes past the
`pmap_mapdev` window — kernel-VA memory corruption with partially
attacker-chosen data (RSS table bytes are host-derived; intr_coal value is
a root-settable int; descriptors contain DMA addresses).

Related same-family sloppiness in the same flow: **`mxge_rx_ring_t.mask`
and `cl_size` are `int16_t`** (if_mxge_var.h:65-66) while the entry counts
derive from the NIC-returned `GET_RX_RING_SIZE`/`GET_SEND_RING_SIZE`
(`mxge_alloc_slices` :3960-3961, `mxge_alloc_rings` :3194-3196): a
ring size ≥ 512 KiB (entries ≥ 32768) wraps the mask negative
(:3007-3009) and `idx = rx->cnt & rx->mask` sign-extends garbage.

Contrast: `mxge_adopt_running_firmware` *does* bounds-check its
device-supplied header offset against `sc->sram_size` (:867) — the check
pattern exists in the file; the loci above simply never got it.

## Threat model

Hostile/faulting PCIe device (same premise as DF-3716/3718 and the
igb/bge/em device-trust findings).  Not reachable by network input alone.

## Verification

Hardware-gated; source-certain; `inconclusive` per family convention.

## Fix

`fix.diff` adds `mxge_sram_range_valid()` and applies it at all four loci
(intr-coal/ack/deassert offsets, both send-offset branches, both rx-offset
commands, RSS table and key), failing open with `ENXIO`/`EIO`.  git-apply
clean.  (int16_t mask widening is a larger mechanical change; flagged in
the diff comment in the finding text only.)
