# DF-4079 VERDICT — oce_rx pkt_size/fragment-count desync

## Status: REPRODUCED (baseline invariant-violation + m_copydata panic; fix validated on rebuilt kernel)

Guest: DragonFly dfbsd 6.5-DEVELOPMENT #0 (stock) and #1 (patched), x86_64.
Method: production-handler KLD dispatch rig (the DF-4106/DF-4266/if_et
evidence class) — no OneConnect hardware needed because `device oce` is
compiled into the guest's X86_64_GENERIC kernel.

## What ran (all production code, kernel-loader bound)

1. Rig externs: `oce_rq_handler`, `oce_alloc_rx_bufs`,
   `oce_create_ring_buffer`, `oce_destroy_ring_buffer`,
   `oce_free_posted_rxbuf` — resolved against the running kernel's symbol
   table at kldload (verified: dispatched handler address
   0xffffffff805c9e50 = nm(1) `T oce_rq_handler`).
2. Fabricated post-attach state: BE3 softc (flags, ring sizes,
   rq_frag_size=2048 per oce_if.c:236), verbatim `oce_rq_init` DMA replay
   (oce_queue.c:429-455: same tag params, 1024 dmamaps, real ring from the
   kernel's own `oce_create_ring_buffer`), RX CQ ring (256×16B), real
   ifnet with an if_input inspection shim, MMIO BAR stand-in pages
   (register offsets all < 0x140, oce_hw.h:64-88).
3. Posted 16 real clusters via REAL `oce_alloc_rx_bufs` (m_getcl +
   bus_dmamap_load_mbuf_segment + RQEs + doorbell to the stand-in page).
4. Crafted CQEs as firmware would DMA them (DW_SWAP is a no-op on LE,
   oce_if.h:1114): case 1 `pkt_size=16383, num_fragments=1, valid=1`;
   case 2 `pkt_size=16383, num_fragments=7, valid=1`.
5. Dispatched REAL `oce_rq_handler(rq)` → static `oce_rx` (confirmed in
   the panic backtrace as `oce_rx.isra.10`) → `sc->ifp->if_input(...)`.

## Observed (stock kernel, run.log / panic.txt)

- case 1: delivered chain `[m_len=2048]` with `m_pkthdr.len=16383`
  → 14335 phantom bytes.
- case 2: delivered chain of 7×2048=14336 bytes with
  `m_pkthdr.len=16383` → 2047 phantom bytes (max representable chain data
  7×2048=14336 < 16383=max 14-bit pkt_size: the trust-boundary gap).
- `rq->rx_stats.rx_bytes += 32766` — stats count phantom bytes
  (oce_if.c:1381).
- Deterministic: baseline run twice, identical results.
- panic mode (panic.txt): `panic: m_copydata: offset > size of mbuf
  chain` — the exact cited KASSERT (sys/kern/uipc_mbuf.c:1679-1680,
  INVARIANTS kernel), backtrace
  `m_copydata() ← df4079_input() ← oce_rx.isra.10() ← oce_rq_handler()`.
  The rig's m_copydata call models any offset-walking stack consumer
  (forwarding/fragmentation/ICMP-error paths) that trusts pkthdr.len.

## Impact ceiling on this guest

Kernel panic (DoS) demonstrated. Escalation beyond DoS would require the
frame bytes (also firmware-controlled) to steer a stack consumer into an
OOB copy — the primitive is the 2047-byte phantom region the stack will
read past the chain's real end; on this guest the walk hits the KASSERT
first. Threat model: buggy/malicious NIC firmware or device DMA; not
remotely reachable without the NIC writing the CQE.

## Fix validation (fix.diff / fix_build.log / fix_run.log)

fix.diff = residual-length check in `oce_rx` (drop when `len != 0` after
the fragment loop). Applied to guest /usr/src (md5-identical to audit tree
before patch), `make -j6 nativekernel KERNCONF=X86_64_GENERIC` +
installkernel (full 41592-line log: fix_build.log), rebooted into
`#1: Thu Oct 15 13:06:11 UTC 2026`.

- baseline on patched kernel: both crafted CQEs dropped —
  `chains delivered to if_input: 0; invariant violations: 0;
  rx_pkts=0; rx_bytes=0` → `FIX CONFIRMED` (handler address moved to
  0xffffffff805c9e80 = the rebuilt kernel's own oce_rq_handler).
- panic mode on patched kernel: SURVIVED (no chain ever reaches
  if_input, so the m_copydata dispatch never happens).

Distinct from DF-1371 (pckts[] array over-walk): DF-4079 needs no RQ-array
inconsistency — the RQ walk here is perfectly legal; only the chain length
contract is violated.

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