# DF-4081 VERDICT — oce_tso_setup pre-pullup header reads

## Status: UNTESTED (hardware-gated; no oce device in QEMU)

Source trace:

- oce_if.c:842-853: CSUM_TSO frames take oce_tso_setup() on every TSO send.
- TSO enabled by default: oce_if.c:1697-1699 adds IFCAP_TSO to capabilities,
  oce_if.c:1707 sets if_capenable = if_capabilities.
- oce_if.c:1046-1073 dereferences eh / ip / ip6 / th (th->th_off at
  m_data+14+ip_hl*4, up to byte ~74 of the first mbuf) with no m_len check;
  the m_pullup that would guarantee contiguity is at oce_if.c:1080, after the
  reads.
- If the TCP header lives in a later mbuf (legal chain shape from the socket
  layer), th->th_off reads stale bytes past m_len but inside the cluster →
  bogus total_len → m_pullup failure → silent ENXIO drop (oce_if.c:849-852),
  or a wrong-size pullup consumed by the WQE builder.

Distinct from DF-1373 only in function (oce_check_ipv6_ext_hdr vs
oce_tso_setup) — same defect class, both live on the TX path.

## Fix

```diff
 	m = *mpp;
+
+	m = m_pullup(m, ETHER_HDR_LEN + sizeof(struct ip6_hdr) +
+			sizeof(struct tcphdr));
+	if (m == NULL)
+		return NULL;
+	*mpp = m;
 
 	if (M_WRITABLE(m) == 0) {
```
(re-derive eh/ip6/th after the pullup; existing pointer math then stays valid
because m_pullup preserves data offsets.)

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

(No fix.diff for this item: documented recommendation only - see Fix above.)
