From: Nick Simpson <nick.simo@gmail.com>
To: Magnus Karlsson <magnus.karlsson@intel.com>,
Maciej Fijalkowski <maciej.fijalkowski@intel.com>,
David Ahern <dsahern@kernel.org>,
Ido Schimmel <idosch@nvidia.com>
Cc: Stanislav Fomichev <sdf@fomichev.me>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
Pablo Neira Ayuso <pablo@netfilter.org>,
Florian Westphal <fw@strlen.de>, Phil Sutter <phil@nwl.cc>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Jesper Dangaard Brouer <hawk@kernel.org>,
John Fastabend <john.fastabend@gmail.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
Willem de Bruijn <willemb@google.com>,
Jason Xing <kerneljasonxing@gmail.com>,
Song Yoong Siang <yoong.siang.song@intel.com>,
Rusty Russell <rusty@rustcorp.com.au>,
Max Krasnyansky <maxk@qualcomm.com>,
Sridhar Samudrala <sri@us.ibm.com>,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Randy Dunlap <rdunlap@infradead.org>,
netdev@vger.kernel.org, linux-doc@vger.kernel.org,
bpf@vger.kernel.org, netfilter-devel@vger.kernel.org,
coreteam@netfilter.org, linux-kernel@vger.kernel.org
Subject: [PATCH net 0/3] xsk, ipv6: validate user-supplied checksum offsets
Date: Wed, 21 Oct 2026 19:03:26 +0100 [thread overview]
Message-ID: <20261021180329.26358-1-nick.simo@gmail.com> (raw)
In copy mode, AF_XDP turns the csum_start/csum_offset of
XDP_TXMD_FLAGS_CHECKSUM into a CHECKSUM_PARTIAL skb after checking only
that the checksum fits in the frame. Sent over a veth into a namespace
that forwards IPv6 with nf_defrag_ipv6, the checksum is then completed
after the forward hook has accepted the packet, at an offset in the IPv6
header chosen by the sender; with csum_start before the network header,
skb_checksum_help() warns. Patch 1 has the details and the trace.
This is the AF_XDP counterpart of the virtio_net_hdr issue fixed for
IPv4 by commit 6785011f8b16 ("ipv4: validate checksum_start before
completing checksum") and addressed by the "more virtio-net csum
hardening" series [1], which does not cover AF_XDP.
Patch 1 is the fix: CHECKSUM_PARTIAL is kept only for the TCP or UDP
checksum of an unfragmented IPv4/IPv6 packet, not IP-in-IP or GRE
encapsulated, on an Ethernet device; other requests are completed in
software at the sender. Frames without a linear part
(IFF_TX_SKB_NO_LINEAR) are left unchanged. One visible change: a request
on a frame that is itself an IP fragment is completed over that fragment
alone, as a device would, so the reassembled datagram no longer has a
valid transport checksum and conntrack marks it invalid; before, if
every fragment carried a request, it stayed CHECKSUM_PARTIAL and was
completed on refragmentation.
Patch 2 documents the new behaviour in xsk-tx-metadata.rst. It is kept
separate so that patch 1 stays within the stable size limit.
Patch 3 is defence in depth: the IPv6 counterpart of
ip_check_csum_start() on the two IPv6 fragmentation paths,
ip6_fragment() and br_ip6_fragment(). For IPv4 the check is also
called from nfnetlink_queue, xt_CHECKSUM and xfrm_output; their IPv6
counterparts are not changed here, and a check at reassembly time would
cover more. Patch 1 does not depend on it, and it is not marked for
stable.
Testing, on netdev/net 82e31923c055, arm64 under QEMU:
- reproducer (fragmented IPv6/UDP over veth into a namespace with an
nftables forward rule on "ip6 saddr", csum_start/csum_offset 22/22;
an unfragmented packet with 14/22 and TX checksum offload off on the
egress veth; csum_start 20): without the series the source address is
rewritten after the forward hook accepted the packet, and
skb_checksum_help() warns. With the series, or with patch 1 alone,
nothing is rewritten after the accept and there is no warning; with
patch 3 alone the fragmented cases are not sent on (ip6_fragment()
drops them) and the unfragmented case is not covered
- a legitimate IPv6/UDP request (csum_start at the UDP header, offset 6)
is still sent CHECKSUM_PARTIAL and delivered to a UDP socket
- which requests stay CHECKSUM_PARTIAL, observed on the veth peer with
PACKET_AUXDATA: IPv4/UDP, IPv4/TCP, IPv4 with options, IPv6/UDP, IPv6
with a hop-by-hop header and VLAN-tagged IPv6/UDP stay partial; a
wrong csum_offset, csum_start in the IP header, IPv4 and IPv6 first
fragments, IPIP and ICMP are completed in software with the correct
value. Without the series all of them stay partial.
- tools/testing/selftests/bpf: test_progs -t xdp_metadata passes with
and without the series
- on a kernel with KASAN, PROVE_LOCKING, PROVE_RCU,
DEBUG_ATOMIC_SLEEP, DEBUG_PREEMPT, DEBUG_PAGEALLOC and
DEBUG_OBJECTS_RCU_HEAD, no warnings: with the series, the
reproducer, the classification test and the selftest; without it,
the selftest and the legitimate request
- W=1 and sparse (C=1) on the changed files in allmodconfig builds for
arm64, x86_64, i386 and s390: no warnings, with or without the
series; checkstack unchanged; arm64 allnoconfig and an INET=n build
with XDP_SOCKETS=y build; checkpatch --strict is clean; htmldocs for
networking builds without warnings for xsk-tx-metadata.rst
- arm64 allmodconfig and allyesconfig with W=1 build, with no warning
in the changed files (CONFIG_WERROR and the DRM *_WERROR options
were turned off: with gcc 15, existing W=1 warnings in unrelated
files otherwise stop the build)
Not tested: IFF_TX_SKB_NO_LINEAR (virtio_net) devices, multi-buffer
frames, an attached BPF flow dissector, a sender in an unprivileged
user namespace, x86 at runtime, and patch 3 with tun/tap or packet
socket sources of CHECKSUM_PARTIAL (the same header rewrite through a
tap device was reproduced on mainline earlier, but not re-run with
patch 3).
The issue was found, and the patches and tests prepared, with LLM
assistance (see the Assisted-by tags). I have reviewed the changes and
the test results. A reproducer is available on request.
[1] https://lore.kernel.org/r/cover.1792411304.git.mst@redhat.com
Nick Simpson (3):
xsk: validate checksum offload requests in copy mode
xsk: document checksum offload handling in copy mode
ipv6: validate checksum_start before fragmenting
Documentation/networking/xsk-tx-metadata.rst | 7 ++-
include/net/ipv6.h | 12 ++++
net/ipv6/ip6_output.c | 10 +++-
net/ipv6/netfilter.c | 10 +++-
net/xdp/xsk.c | 58 ++++++++++++++++++++
5 files changed, 90 insertions(+), 7 deletions(-)
base-commit: 82e31923c0553fdbfcddcd910ca07952880ca9b9
--
2.53.0
next reply other threads:[~2026-10-21 18:04 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 18:03 Nick Simpson [this message]
2026-10-21 18:03 ` [PATCH net 1/3] xsk: validate checksum offload requests in copy mode Nick Simpson
2026-10-21 18:03 ` [PATCH net 2/3] xsk: document checksum offload handling " Nick Simpson
2026-10-21 18:03 ` [PATCH net 3/3] ipv6: validate checksum_start before fragmenting Nick Simpson
2026-10-21 18:20 ` Eric Dumazet
2026-10-21 18:47 ` Eric Dumazet
2026-10-21 20:02 ` Michael S. Tsirkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261021180329.26358-1-nick.simo@gmail.com \
--to=nick.simo@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=corbet@lwn.net \
--cc=coreteam@netfilter.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@kernel.org \
--cc=fw@strlen.de \
--cc=hawk@kernel.org \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=john.fastabend@gmail.com \
--cc=kerneljasonxing@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maciej.fijalkowski@intel.com \
--cc=magnus.karlsson@intel.com \
--cc=maxk@qualcomm.com \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pablo@netfilter.org \
--cc=phil@nwl.cc \
--cc=rdunlap@infradead.org \
--cc=rusty@rustcorp.com.au \
--cc=sdf@fomichev.me \
--cc=skhan@linuxfoundation.org \
--cc=sri@us.ibm.com \
--cc=willemb@google.com \
--cc=yoong.siang.song@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®