# DF-3958 — VERDICT

**REPRODUCED at the function level** (impact: `panic`), confidence: certain.

## Root cause

`virtqueue_dequeue()` stores the device-controlled used-ring element length
through a `uint32_t *lenp` (`sys/dev/virtual/virtio/virtio/virtqueue.c:544-561`,
store at :560-561). `vtnet_rxeof_merged()` owns an `int len` and passes
`&len` to it (`sys/dev/virtual/virtio/net/if_vtnet.c:1642,1649`). For every
mergeable sub-buffer the driver then clamps and installs that length:

```c
if (m->m_len < len)      /* if_vtnet.c:1663 — SIGNED compare   */
        len = m->m_len;
m->m_len = len;          /* if_vtnet.c:1666 — m_len := device len */
...
m_head->m_pkthdr.len += len;  /* if_vtnet.c:1669 */
m_tail->m_next = m;           /* if_vtnet.c:1670 — chained */
```

A device length >= 0x80000000 becomes a negative `int`; `m->m_len < len`
(2048 < INT_MIN) is false, so the clamp is skipped and `m->m_len` is set
negative. The chain is handed to `ifp->if_input()` at if_vtnet.c:1777.

This is NOT covered by DF-1310 (non-mergeable first buffer, `len += VTNET_RX_HEADER_PAD`
wrap, NULL `m_prev` deref in `vtnet_replace_rxbuf`). Here:

- the first-buffer guards do not protect sub-buffers: the
  `len < hdr_size + ETHER_HDR_LEN` drop (if_vtnet.c:1707) and the
  `vtnet_replace_rxbuf()` walk (if_vtnet.c:1727) run only on the FIRST
  buffer of the merged frame;
- the negative length installs directly into a live mbuf and the packet
  header instead of NULLing a local.

## Impact

- `m2->m_len` negative and `m_head->m_pkthdr.len` negative (proven by the
  harness: `run.log`, sweep section).
- The corrupted chain reaches consumers BEFORE any length validation:
  `ether_input_oncpu()` taps bridge/carp/ng_ether/BPF first
  (`sys/net/if_ethersubr.c:1212-1290`).
- `m_copydata()` on such a chain computes
  `count = min(m->m_len - off, len)` → negative → `(unsigned)0x80000000`
  → `bcopy` of 2 GiB (`sys/kern/uipc_mbuf.c:1686-1695`) — kernel smash /
  panic. `bpf_mcopy()` (`sys/net/bpf.c:1275-1287`) walks into the sub-mbuf
  and copies stale cluster bytes into listener buffers (minor info
  exposure to a BPF listener).
- Plain IP/IPv6 demux drops the frame on `m_pkthdr.len < hdr` checks, so
  the practical ceiling is DoS/panic plus the BPF stale-byte exposure —
  consistent with the Medium severity of its non-mergeable twin DF-1310.

## Why function-level (not live-panicked)

The audit guest's virtio-net device is QEMU's own benign emulation; it
always writes sane used-ring lengths. Crashing the guest's console NIC to
prove the primitive was deemed destructive without adding evidence beyond
the arithmetic — same standard used for DF-1310.

## Fix validation

- `fix.diff` (unsigned clamp `if ((uint32_t)len > (uint32_t)m->m_len)`)
  applies cleanly to `/usr/src` (fixapply2.log).
- Kernel rebuilt `make -j6 nativekernel KERNCONF=X86_64_GENERIC`, rc=0,
  `-Werror` (fix_build.log); installed and booted
  (`#1 Thu Sep 17 05:23:00 UTC 2026`); vtnet0 UP/RUNNING while the whole
  verification session ran over it (patched_boot.txt) — regression-clean.
- Harness AFTER-FIX arm shows `m2->m_len = 2048`, `pkthdr.len = 2074`
  (run.2.log, on the patched kernel).

## Kernel references

- sys/dev/virtual/virtio/net/if_vtnet.c:1642,1649 (int len vs uint32_t store)
- sys/dev/virtual/virtio/net/if_vtnet.c:1663-1671 (signed clamp → negative m_len)
- sys/dev/virtual/virtio/net/if_vtnet.c:1707,1727 (first-buffer-only guards)
- sys/dev/virtual/virtio/net/if_vtnet.c:1777 (if_input of corrupted chain)
- sys/dev/virtual/virtio/virtio/virtqueue.c:544-561 (device len store)
- sys/kern/uipc_mbuf.c:1686-1695 (m_copydata huge bcopy consumer)
- sys/net/bpf.c:1275-1287 (bpf_mcopy stale-byte walk)
- sys/net/if_ethersubr.c:1212-1290 (pre-validation taps)

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