# DF-3736 — emx(4) RX descriptor-length trust (DF-3713 em(4) twin)

## What
`emx_rxeof()` publishes the 16-bit NIC-DMA'd extended-descriptor length with
no bound against the posted buffer:

- `len = le16toh(current_desc->rxd_length);` — sys/dev/netif/emx/if_emx.c:3369
  (`rxd_length` == `wb.upper.length`, 16 bits, DMA-written by the NIC;
  extended descriptors enabled via `E1000_RFCTL_EXTEN`, if_emx.c:3134;
  `E1000_RCTL_SECRC` strips CRC in HW at :3283 so unlike em(4) there is no
  `-4` adjustment anywhere).
- `mp->m_len = len;` — if_emx.c:3401
- `m_pkthdr.len = len` / `+= len` — if_emx.c:3404 / :3413
- posted buffer: `m_getcl()` MCLBYTES=2048 cluster (emx_newbuf:2908-2916),
  front-trimmed by ETHER_ALIGN iff `hw.mac.max_frame_size <= 2046`
  (:2918-2919) → usable DMA span 2046/2048 bytes.

A faulty, erratum-hit, or malicious DMA source writing `0xFFFF` into the
write-back length makes the stack treat 65535 bytes of adjacent kernel heap
as packet data → heap OOB read of up to ~63.5KB per descriptor into
ether_input/BPF/forwarding consumers (kernel heap info leak / panic).

This is the exact twin of em(4)'s DF-3713 (positive direction of DF-1188).
The 2-byte ETHER_ALIGN DMA overflow window is the already-filed DF-1197
(emx) / DF-3712 (em) — NOT re-filed here.

## Build / run (guest or any DragonFly box)
```
cc -O -o /root/emx_bounds_harness /root/emx_bounds_harness.c
/root/emx_bounds_harness
```

## Expected output
Section [B] prints, for `desc_len=0xFFFF`: `m_len=65535 claims 63489 bytes
past the 2046-byte posted cluster: kernel heap OOB read of up to 63489 bytes
per descriptor` (and 63487 past the 2048-byte untrimmed cluster), plus the
honest-frame safe cases.  Exit code 1.

## Device-side injection (not possible on this guest)
The audit guest has no emx hardware (`kldload if_emx` loads the module, no
interface attaches).  On hardware, injecting a corrupt write-back length
requires one of: (a) surprise-removal/erratum register-DMA state, (b) a
malicious PCIe device performing peer-to-peer DMA into the descriptor ring,
or (c) an emulated-e1000 hypervisor bug.  Per the em(4) family convention
this is recorded as source-certain / runtime-hardware-gated
(`inconclusive`).
