# DF-3736 — VERDICT

**Status: inconclusive (source-certain, runtime hardware-gated) — same
convention as the em(4) twin DF-3713.  reproduced=0, impact=none on this
guest.**

## Reproduced what, and why not more
The guest kernel is DragonFly 6.5-DEVELOPMENT with `if_emx.ko` loadable but
no emx PCI device present (`kldload if_emx` → module loads, `ifconfig -l` →
`vtnet0 lo0`).  The descriptor write-back path can therefore only be
exercised by source-line analysis plus the bound-math harness, which was
built and run on the guest (`run.harness.log`, exit 1):

- `desc_len=0xFFFF` (non-EOP and EOP) → `m_len=m_pkthdr.len=65535` in a
  2046-byte (trimmed) or 2048-byte posted cluster → **63489/63487-byte
  heap OOB read claim**, demonstrated arithmetically against the exact
  posting math of `emx_newbuf()` (if_emx.c:2908-2919).
- honest frames (1500 std, 2048 jumbo fragment) verified in-bounds — the
  check I propose never rejects honest hardware.

## Root cause chain (path:line)
1. NIC DMA-writes the extended RX descriptor incl. 16-bit
   `wb.upper.length` (descriptor format `sys/dev/netif/emx/if_emx.h:204-211`).
2. `emx_rxeof()` reads it: `len = le16toh(current_desc->rxd_length)` —
   `sys/dev/netif/emx/if_emx.c:3369`.  No comparison against the posted
   span anywhere in the loop (:3352-3461).
3. Publishes it: `mp->m_len = len` (:3401), `m_pkthdr.len = len` (:3404),
   `m_pkthdr.len += len` (:3413 for chained fragments).
4. Frame handed to `ifp->if_input` (:3453) → ether_input/BPF/socket
   consumers walk `m_len`/`m_pkthdr.len` bytes of a 2048-byte cluster.

Unlike em(4) (DF-3713) there is **no CRC adjustment and no prev_len_adj
logic** (emx sets `E1000_RCTL_SECRC`, CRC stripped in HW, :3283) — the
em(4)-specific negative-m_len variant does not exist here; the positive
overshoot (OOB read / info leak) does, identically.

## Threat model
Not reachable by an unauthenticated remote peer with a *functioning* NIC
(the MAC writes the true received length).  Reachable via: faulty/erratum
NIC writing corrupt write-backs, surprise removal (stale/coherent-memory
corruption), or a malicious/emulated PCIe DMA source.  Impact ceiling:
kernel heap disclosure into the network stack (leak) or panic.  Family
severity: Medium (matches DF-3713).

## Fix
`fix.diff` (git-apply clean against the read-only tree): discard the frame
(same `discard:` path the error/newbuf-failure cases already use) when
`len == 0` or `len` exceeds the trim-aware posted span.  Cannot be runtime-
validated on this guest (no hardware) → `fix_status: not_testable`, but the
harness's honest-frame cases prove the bound never rejects legitimate
traffic (fragment ≤ 2048 untrimmed; ≤ 2046 trimmed).

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