# DF-3780 VERDICT — REPRODUCED (mechanism, protocol-replica) — impact: dos (unbounded kernel memory leak)

## Bottom line
Every field of the TX completion descriptor is host-controlled, and
`vmxnet3_txq_eof()` uses `txcd->eop_idx` to advance `vxtxr_next` with no
validation against the outstanding-descriptor window (if_vmx.c:1966). A
completion naming a later packet's EOP hops `vxtxr_next` over intermediate
SOP slots; their `vtxb_m` mbufs become unreachable and are leaked forever
when `vmxnet3_txq_encap()` overwrites the slot at if_vmx.c:2904.
`VMXNET3_TXRING_AVAIL()` (if_vmxvar.h:76-81) simultaneously reports the ring
as empty (avail=511/512 while a packet is outstanding), so the desync also
breaks the flow-control invariant between guest and host.

## Proof on the guest (DragonFly 6.5-DEVELOPMENT X86_64_GENERIC)
Verbatim replica of txq_eof + encap slot bookkeeping, hostile host forges one
completion per two transmitted packets (eop_idx = head-1). 1000 cycles:

| measurement | before | after run1 | after run2 |
|---|---|---|---|
| mbuf clusters in use | 256 | 1256 | 2256 |
| network memory | 515 K | 2515 K | 4515 K |
| replica counters | — | alloc=2000 freed=1000 LEAKED=1000 | alloc=4000 freed=2000 LEAKED=2000 |

(run.log; dmesg: "after cycle 1: avail=511 (ring claims EMPTY) while P2 mbuf
still outstanding".) Exactly one 2048-byte cluster leaked per forged
completion; linear and unbounded; leaked clusters persist across module
unload (permanent until reboot). At guest line rate this drains the 33k
cluster pool (mb_map) in seconds-to-minutes → "requests for memory denied"
→ network DoS.

## Why not worse
- The index stays in-bounds (`% vxtxr_ndesc`), so no OOB access from eop_idx
  itself — impact is leak/livelock, not corruption.
- Double-load of a still-loaded dmamap on slot reuse: DFly x86_64
  `bus_dmamap_load_mbuf_segment()` (busdma_machdep.c:870-912) has no
  "already loaded" guard and simply overwrites the mapping — no panic on this
  platform (verified by source); on bounce-buffer platforms this would
  additionally corrupt bounce-page accounting.

## Fix validation
Kernel-build validation not possible (no vmxnet3 device on the KVM guest).
Fix LOGIC validated in the same replica: test 900 (fixrun.log) adds the
window check and frees every mbuf in [next .. eop_idx] exactly once —
same hostile inputs, fresh module load: `alloc=2000 freed=2000 LEAKED=0`,
cluster count unchanged. fix.diff authors that logic for if_vmx.c.

## Kernel refs
sys/dev/virtual/vmware/vmxnet3/if_vmx.c:1938-1967 (txq_eof),
if_vmx.c:2878-2928 (encap slot bookkeeping; the overwrite at 2904),
if_vmxvar.h:76-81 (TXRING_AVAIL), if_vmxreg.h:115-125 (txcompdesc).

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