[PATCH dpdk] net/tap: use offsets provided by rte_net_get_ptype
Stephen Hemminger
stephen at networkplumber.org
Wed Apr 22 18:32:15 CEST 2026
On Wed, 22 Apr 2026 15:36:16 +0200
Robin Jarry <rjarry at redhat.com> wrote:
> Instead of guessing what are the proper header lengths, pass
> a rte_net_hdr_lens struct to rte_net_get_ptype and use it to get the
> proper header lengths/offsets in tap_verify_csum.
>
> Signed-off-by: Robin Jarry <rjarry at redhat.com>
> ---
AI review feedback spotted some things I didn't
On Wed, 22 Apr 2026 15:36:16 +0200
Robin Jarry <rjarry at redhat.com> wrote:
> Instead of guessing what are the proper header lengths, pass
> a rte_net_hdr_lens struct to rte_net_get_ptype and use it to get the
> proper header lengths/offsets in tap_verify_csum.
The two bounds checks this patch drops are not redundant with the new
l4_off check and need to stay in some form:
- if (l2_len + rte_be_to_cpu_16(iph->total_length) >
- rte_pktmbuf_data_len(mbuf))
- return;
...
- if (l2_len + l3_len + rte_be_to_cpu_16(iph->payload_len) >
- rte_pktmbuf_data_len(mbuf))
- return;
rte_ipv4_udptcp_cksum_verify() -> __rte_ipv4_udptcp_cksum() does:
l3_len = rte_be_to_cpu_16(ipv4_hdr->total_length);
...
l4_len = l3_len - ip_hdr_len;
cksum = rte_raw_cksum(l4_hdr, l4_len);
and the IPv6 variant reads payload_len the same way. Both are untrusted
values from the wire. Without the checks above, a packet whose
total_length / payload_len exceeds what was actually received causes
rte_raw_cksum() to read past the valid data - uninitialized tail room at
best, outside buf_len at worst. The IP/L4 CKSUM flags set on the mbuf
will then be computed over stale memory.
These checks were added deliberately in:
1168a4fd193 ("net/tap: add buffer overflow checks before checksum")
Please restore equivalent validation after rte_net_get_ptype(), e.g.
check iph->total_length (IPv4) and hdr_lens->l3_len + iph->payload_len
(IPv6) against rte_pktmbuf_data_len(mbuf) - hdr_lens->l2_len before
calling the checksum verifier.
One other thing: rte_net_get_ptype() returns RTE_PTYPE_L3_IPV6_EXT when
IPv6 extensions are present. The new "else if (l3 != RTE_PTYPE_L3_IPV6)"
clause falls through to return without setting any CKSUM flag for that
case. That matches pre-patch behavior, but the comment the patch removed
was the only thing documenting it. Either accept IPv6_EXT here (l3_len
now spans the extensions, so the existing helpers work as long as the
next header is TCP/UDP) or keep the comment.
Nit: the memset(&hdr_lens, 0, ...) runs on every Rx packet even when
RX_OFFLOAD_CHECKSUM is disabled. Moving it plus the &hdr_lens argument
inside the offload branch (passing NULL otherwise) avoids that.
I prefer initialization instead of memset, less error prone and easier.
More information about the dev
mailing list