# DF-1410 — xe(4) RX length missing upper bound (heap overflow)

## Verdict
**REPRODUCED (source-level harness).** The bug is real; impact ceiling is
remote (unauthenticated, same-L2-segment) heap overflow of a 2 KiB mbuf
cluster, with overflow sizes from ~6 KiB (long packet) up to ~63 KiB (RBC<4
unsigned wrap). The kernel code path cannot be exercised on this guest
because QEMU does not emulate any PCMCIA bridge or the Xircom CE hardware —
`xe0` does not exist in `pciconf -lv`. The fix.diff applies cleanly and
`nativekernel` succeeds (rc=0); no run-time exercise is possible because the
device is absent.

## Mechanism (`sys/dev/netif/xe/if_xe.c`)
1. Line 750: `u_int16_t len;`
2. Line 752: `len = XE_INW(XE_RBC) - ETHER_CRC_LEN;` — no mask against
   `XE_RBC_BYTE_COUNT` (`if_xereg.h:269`, 0x1FFF) so the 3 flag bits in the
   high half contaminate the count; no upper-bound check vs `MCLBYTES`
   (2048); no lower-bound check that `RBC >= ETHER_CRC_LEN`, so an RBC value
   of 0..3 wraps to `len = 0xFFFC..0xFFFF`.
3. Lines 775-782: `MCLGET` attaches a 2 KiB cluster; line 784 `m_data += 2`
   reduces the usable window to `MCLBYTES - 2`.
4. Lines 822/826: `bus_space_read_multi_2(bst, bsh, XE_EDP, ehp, (len+1)>>1)`
   copies `2*ceil(len/2)` bytes from the card into that cluster window — for
   any oversized or wrapped `len`, this writes thousands of bytes past the
   cluster into the adjacent kernel heap.

Sibling drivers (`dc`, `fxp`, `rl`, etc.) all mask their RX-length register
and bound against `MCLBYTES`; xe is the outlier.

## Harness proof (`harness.c`)
Uses the genuine register layout (`XE_RBC_BYTE_COUNT = 0x1fff`), the genuine
`len = RBC - ETHER_CRC_LEN` arithmetic, and the genuine
`(len+1)>>1` word count. 4 of 7 representative inputs (silicon-long 8184 B
packet, plus RBC=0/1/3 wraps) produce overflows of 6 KiB..63 KiB. The fixed
variant (mask + range-check) accepts the legitimate packets and rejects the
oversized/wrapped ones:

```
case                                RBC  bug_len    oob_B  fix_len    oob_B
silicon long 8184B packet          8184     8180     6134       -1        0
RBC=0  (wrap to 0xFFFC)               0    65532    63486        0        0
RBC=1  (wrap to 0xFFFD)               1    65533    63488        0        0
RBC=3  (wrap to 0xFFFF)               3    65535    63490        0        0
Buggy driver: 4/7 cases overflow the 2KiB mbuf cluster
```

## Exploit-chain note
This is a remote unauthenticated heap-overflow primitive on real hardware.
QEMU has no Xircom PCMCIA device, so the kernel-side chain cannot be
exercised here. On a deployed Xircom CE2 system, every received long packet
(8 KiB) or underflowed RBC corrupts adjacent heap deterministically; this is
a credible remote heap-grooming → kernel-code-exec primitive in a real
deployment. Documented as primitive characterization; impact ceiling is
remote heap corruption.

## PoC changes
- Original PoC folder had no source (`build.sh`/`run.sh` were placeholders).
- Added `harness.c` plus repro scripts, env, build/run logs, fix.diff,
  VERDICT.md, manifest.json.

## Fix
`fix.diff` masks `XE_RBC` against `XE_RBC_BYTE_COUNT`, requires
`len >= ETHER_CRC_LEN`, and rejects `len - ETHER_CRC_LEN > MCLBYTES - 2 - 1`
before attaching the cluster. This matches the pattern every sibling NIC
driver uses. Matches the finding markdown proposal.

## Fix-validation
`patch -p1 --forward` succeeds (hunk #1 at line 749). `nativekernel`
completes with rc=0 (saved as `fix_build.log`). The kernel-side before/after
cannot be exercised because the device is absent → `fix_status:
"not_testable"`. The diff is verified to apply and compile, and the changed
logic is traced to close the cited overflow.
