summaryrefslogtreecommitdiff
path: root/net/core/skbuff.c
AgeCommit message (Collapse)Author
9 daysnet: fix frag_list leak in skb_segment_list() error pathEric Dumazet
skb_segment_list() detaches the frag_list from the head skb and moves its members one by one to the skb->next chain. On error, err_linearize frees that chain with kfree_skb_list(skb->next), relying on the members not yet processed to still be linked after the current one. This does not hold when the current member was shared: it is replaced by skb_clone(), and __skb_clone() clears ->next. If __skb_linearize() then fails on that clone, the remaining members are no longer reachable from skb->next nor from skb_shinfo(skb)->frag_list, and they leak. The skb_shared() error branch already relinks nskb->next to list_skb before jumping to err_linearize. Do it unconditionally right after nskb is added to the chain, so every error exit sees the remaining members. On the last member list_skb is NULL, which still terminates the chain. Fixes: 53475c5dd856 ("net: fix use-after-free when UDP GRO with shared fraglist") Signed-off-by: Eric Dumazet <edumazet@kernel.org> Cc: Simon Polack <spolack+git@mailbox.org> Reviewed-by: Willem de Bruijn <willemb@google.com> Reviewed-by: Wang Zhan <wang.zhan@smartx.com> Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://patch.msgid.link/20261021161858.761205-1-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
9 daysnet: skbuff: propagate shared-frag marker in skb_zerocopy()Zizhen Liu
skb_zerocopy() moves frag descriptors from @from into @to and takes a reference on each frag, but it does not copy skb_shinfo(from)->flags into skb_shinfo(to)->flags. A destination skb holding the same page-cache backed frags as the source therefore reports skb_has_shared_frag() as false. That breaks the invariant relied on by later in-place writers. ESP input checks skb_has_shared_frag() before deciding whether an uncloned nonlinear skb can skip skb_cow_data(); with the marker lost, an skb that skb_zerocopy() built for nfnetlink_queue or for an openvswitch upcall is decrypted in place, letting an unprivileged user write into the page cache of a root-owned read-only file. Propagate SKBFL_SHARED_FRAG when frag descriptors are copied, as done for the other frag-transfer helpers. Fixes: af2806f8f90a ("net: Export skb_zerocopy() to zerocopy from one skb to another") Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags") Cc: stable@kernel.org Signed-off-by: Zizhen Liu <pointerliu@126.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Link: https://patch.msgid.link/20261022104217.1852191-1-pointerliu@126.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
10 daysMerge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netPaolo Abeni
Merge in late fixes in preparation for the net-next PR. Conflicts: net/netfilter/nf_conntrack_netlink.c cd37ab22a74e0 ("netfilter: nf_conntrack_netlink: fix inverted IPv6 tuple filter") 1ae2d094b0200 ("netfilter: ctnetlink: fix inverted IPv6 address match in dump filter") Adjacent changes: drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c 8830e65ed46de ("net: use assign_bit() where applicable") 07bd391eb957 ("octeontx2-af: Fix CQ enable state tracking after AQ writes") net/core/sock.c 31c5ea8a3296 ("ipv6: Remove IPV6_ADDRFORM.") 31b564f70d88 ("net: use the full socket in sk_mc_loop()") net/mptcp/protocol.h 0cb6910130a3 ("mptcp: remove thmac from subflow ctx") 7538fa33bb2f ("mptcp: fix subflow bitfield misuse") Signed-off-by: Paolo Abeni <pabeni@redhat.com>
10 daysnetmem: rename get/put_net_iov() to net_iov_inc/dec_ref()Mina Almasry
Follow the object_action() naming convention for net_iov non-page_pool reference helpers by renaming get_net_iov() and put_net_iov() to net_iov_inc_ref() and net_iov_dec_ref(), and renaming net_devmem_get_net_iov() and net_devmem_put_net_iov() to net_devmem_net_iov_inc_ref() and net_devmem_net_iov_dec_ref(). Use *_inc_ref() and *_dec_ref() rather than *_ref() and *_unref() to pair symmetrically with netmem_inc_ref() and netmem_dec_ref() (since netmem_ref is already the typedef for the generic network memory handle). Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261021015558.4124825-2-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
11 daysnet: skbuff: don't copy alloc_cpu in skb header copiesCarolina Jubran
Commit 68822bdf76f1 ("net: generalize skb freeing deferral to per-cpu lists") added alloc_cpu to struct sk_buff and placed it in the headers group copied by __copy_skb_header(). This is wrong for newly allocated skbs. For example, skb_segment() allocates a new skb and records the current CPU in alloc_cpu, but __copy_skb_header() overwrites it with the value from the original skb. If the original skb was allocated on another CPU, the segment may later be treated as remotely allocated and unnecessarily deferred there when it is freed. Move alloc_cpu out of the headers group so it is preserved across header copies. Copy it explicitly in skb_clone(), which allocates the skb object directly instead of going through __alloc_skb(). This was discovered while investigating a throughput regression with software IPsec. The load used 512 IPsec tunnels carrying traffic over VXLAN, with 512 parallel iperf3 flows and an MTU of 4500. Before the fix: 16.09% queued_spin_lock_slowpath | --15.90%--_raw_spin_lock_irqsave | --9.37%--__slab_free kfree skb_release_data napi_consume_skb mlx5e_poll_tx_cq After the fix: 6.84% queued_spin_lock_slowpath | --6.57%--_raw_spin_lock_irqsave | --5.00%--__slab_free kfree skb_release_data napi_consume_skb mlx5e_poll_tx_cq Fixes: 68822bdf76f1 ("net: generalize skb freeing deferral to per-cpu lists") Signed-off-by: Carolina Jubran <cjubran@nvidia.com> Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com> Reviewed-by: Björn Töpel <bjorn@kernel.org> Reviewed-by: Jason Xing <kerneljasonxing@gmail.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20261019174152.2932829-1-cjubran@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
12 daysnet: kunit: test netmem, page_pool, and skb frag refcountingMina Almasry
Verify that non-pp (page._refcount / binding->ref) and page_pool (pp_ref_count) references stay balanced without cross-counter leaks or underflows across regular pages, page_pool pages, non-pp net_iovs, and page_pool net_iovs with both pp_recycle=0 and pp_recycle=1. Cover get/put_net_iov(), get/put_netmem(), napi_pp_get/put_page(), skb_netmem_ref/unref(), skb_frag_ref/unref(), pskb_copy(), skb_zerocopy(), skb_shift(), skb_split(), skb_try_coalesce(), skb_release_data() (clones, unclone ordering, pskb_extract(), and skb_morph()), skb_segment(), and devmem tcp_recvmsg_dmabuf() / SO_DEVMEM_DONTNEED. Export skb_shift() via EXPORT_SYMBOL_IF_KUNIT() so the test links when built as a module (CONFIG_NET_TEST=m). Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Link: https://patch.msgid.link/20261014173945.373295-7-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
12 daysnet: skbuff: use skb_frag_ref() in skb_try_coalesce()Mina Almasry
skb_pp_frag_ref() was introduced solely to work around skb_frag_ref() ignoring skb->pp_recycle and incrementing the non-pp backing refcount. Now that skb_frag_ref() handles both pp_recycle=1 and pp_recycle=0 symmetrically, call skb_frag_ref() directly in skb_try_coalesce() and remove skb_pp_frag_ref(). Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261014173945.373295-6-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
12 daysnet: skbuff: replace __skb_frag_ref() with symmetric skb_netmem_ref()Mina Almasry
Previously, __skb_frag_ref() and skb_frag_ref() unconditionally incremented the non-pp backing refcount via get_netmem(), while skb_frag_unref() decremented pp_ref_count whenever skb->pp_recycle was set. Ref-ing a page_pool fragment into a pp_recycle=1 SKB (or clearing pp_recycle=0 on an uncloned SKB while clones still held pp_recycle=1) leaked the backing non-pp refcount and underflowed pp_ref_count across IP-TFS, skb_split(), skb_shift(), and cloned unclone paths. Replace __skb_frag_ref() with skb_netmem_ref(netmem, recycle) as the exact counterpart to skb_netmem_unref(netmem, recycle): - Keep skb->pp_recycle intact in skb_release_data() so uncloning paths (pskb_expand_head() and pskb_carve_inside_{header,nonlinear}()) keep trading pp_ref_count references symmetrically across clones. - Propagate pp_recycle and call skb_frag_ref() on the destination SKB in __pskb_copy_fclone(), skb_zerocopy(), skb_split(), skb_shift(), and skb_segment(). - Linearize an output segment's existing frags in skb_segment() before attaching frags from a frag_list SKB with a different pp_recycle bit, since each output segment carries a single pp_recycle bit. - Use skb_frag_ref() in xfrm_iptfs, chcr_ktls, and cassini, and call get_netmem() directly in veth and tls_device_fallback where callers explicitly take a raw non-pp reference. Found by code inspection while reviewing the IP-TFS pp_ref_count fix [1] and confirmed with the KUnit tests added later in this series; not observed in production. The xfrm_iptfs, chcr_ktls, cassini, veth, and tls_device_fallback changes are compile-tested only. Link: https://lore.kernel.org/netdev/xfrm-iptfs-pp_ref_count-underflow-v4-1-912fa72106f0@secunet.com/ [1] Cc: Antony Antony <antony.antony@secunet.com> Cc: Stanislav Fomichev <sdf@fomichev.me> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Jesper Dangaard Brouer <hawk@kernel.org> Cc: bpf@vger.kernel.org Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Tested-by: Antony Antony <antony.antony@secunet.com> Link: https://patch.msgid.link/20261014173945.373295-5-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
12 daysnet: skbuff: replace skb_page_unref() and __skb_frag_unref() with ↵Mina Almasry
skb_netmem_unref() Unreferencing a page_pool fragment with recycle=false decrements the non-pp backing refcount instead of pp_ref_count, underflowing the page refcount when the fragment was owned via page_pool (as on mlx4's RX error path). Having both skb_page_unref() and __skb_frag_unref(frag, recycle) made it easy for callers to pass hardcoded recycle=false on SKB-owned fragments. Replace skb_page_unref() and __skb_frag_unref() with skb_netmem_unref(netmem, recycle), which dispatches to napi_pp_put_page() when recycle is true and put_netmem() otherwise: - Use skb_frag_unref(skb, ...) on SKB-owned fragments in mlx4, sky2, tls_strp, and skb_shift() so unrefs always match skb->pp_recycle. - Use put_netmem() directly in tls_device's destroy_record(), which releases raw non-pp page references outside an SKB. Found by code inspection and confirmed with the KUnit tests added later in this series; not observed in production. The mlx4, sky2, and TLS call-site changes are compile-tested only. Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261014173945.373295-4-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
12 daysnet: skbuff: add napi_pp_get_page() and use it in tcp_recvmsg_dmabuf()Mina Almasry
While napi_pp_put_page() releases a page_pool pp_ref_count reference on a netmem, no symmetric helper existed to acquire one, forcing callers like tcp_recvmsg_dmabuf() to open-code atomic_long_inc() on niov->desc.pp_ref_count. Add napi_pp_get_page() to pair symmetrically with napi_pp_put_page(), and use WARN_ON_ONCE(!napi_pp_get_page(netmem)) in tcp_recvmsg_dmabuf() to match WARN_ON_ONCE(!napi_pp_put_page(netmem)) in tcp_release_user_frags(). Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261014173945.373295-3-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
12 daysnetmem: rename __get/__put_netmem() to get/put_net_iov()Mina Almasry
netmems carry both a non-pp backing refcount and a page_pool pp_ref_count. Make the non-pp layer explicit and symmetric across both netmem types: get/put_netmem() dispatches to get/put_page() for pages and get/put_net_iov() for net_iovs, always acquiring or releasing a non-pp reference regardless of page_pool membership. Warn via DEBUG_NET_WARN_ON_ONCE() for net_iov types that do not support non-pp references. Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261014173945.373295-2-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15net: skbuff: remove the BUG_ON()s from skb_shift()Josef Bacik
skb_shift() has two BUG_ON()s. The first fires if the caller asks to shift more than @skb holds. Nothing has been touched yet, and returning 0 already means "shifted nothing", which the TCP callers handle by falling back. Return 0, with a DEBUG_NET_WARN_ON_ONCE() for debug kernels. The second fires if the frags run out before @shiftlen does, but it only checks after the shift has been committed to both skbs, when there's nothing left to back out to. The loop that builds the new frag layout only writes @tgt's frag slots past its nr_frags, and the one branch that modifies @skb's frags also finishes the shift. So if the loop ends with bytes still left to shift, nothing visible has changed yet. That's the same state the MAX_SKB_FRAGS bail-out inside the loop returns 0 from. Move the check up to just before the commit and return 0 there the same way. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Link: https://patch.msgid.link/20261007-b4-skbuff-bug-on-v2-8-b9a5f732895b@toxicpanda.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-15net: skbuff: don't BUG() on a missing head_frag in skb_zerocopy()Josef Bacik
skb_zerocopy() BUG()s if @from has no head_frag and the caller passed hlen == 0, meaning the caller didn't ask for the head to be copied and the head can't be referenced as a page either. The check runs before anything is touched, and skb_zerocopy() already documents -EFAULT for bad skb geometry. Return that, with a DEBUG_NET_WARN_ON_ONCE() for debug kernels. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Link: https://patch.msgid.link/20261007-b4-skbuff-bug-on-v2-7-b9a5f732895b@toxicpanda.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-15net: skbuff: don't BUG() on leftover length in skb_copy_and_csum_bits()Josef Bacik
skb_copy_and_csum_bits() has the same check as skb_checksum(): it BUG()s if it runs out of skb before it runs out of @len. This one gets hit: commit 7d63b6712538 ("icmp: guard against too small mtu") and commit f99cd56230f5 ("net: Remove acked SYN flag from packet in the transmit queue correctly") each fixed a crash here from icmp_glue_bits(). It can't just return, though. Its callers copy into a buffer that is about to go out on the wire, an ICMP error quoting the offending packet for example, so bailing out early would send whatever was left in the rest of that buffer. Zero the part of the buffer we didn't fill and return 0, with a DEBUG_NET_WARN_ON_ONCE() for debug kernels. As with skb_checksum(), the checksum usually won't match the data, so the receiver will usually drop the packet, but either way it carries nothing it shouldn't. @len is an int, so only zero when it is positive; a negative @len from a broken caller must not turn into a huge memset(). Signed-off-by: Josef Bacik <josef@toxicpanda.com> Link: https://patch.msgid.link/20261007-b4-skbuff-bug-on-v2-6-b9a5f732895b@toxicpanda.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-15net: skbuff: don't BUG() on a bad csum_start in skb_copy_and_csum_dev()Josef Bacik
skb_copy_and_csum_dev() copies everything up to the checksum start out of the linear area, and BUG()s if the checksum start is past the end of the linear area. It misses the other direction: a CHECKSUM_PARTIAL skb that has been pulled past its csum_start gives a negative offset, which gets past the check and becomes a ~4GB copy. It also trusts csum_offset when it stores the folded checksum. So far skb_copy_and_csum_bits() BUG()ing on a short skb has covered for that, but once it returns instead, a bad csum_offset would write past the end of the caller's buffer. The function returns void and its callers are drivers copying a frame into a bounce buffer just before handing it to the hardware. There's nothing for them to back out of, so check both ends of csum_start and that the checksum field fits in the frame, and if not, copy the whole frame with skb_copy_bits() without filling in the checksum, with a DEBUG_NET_WARN_ON_ONCE() for debug kernels. The frame goes out with a bad checksum and is dropped by the receiver. If even that copy fails, zero the buffer so the driver doesn't send stale bytes. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Cc: stable? The trailers only have Assisted-by: and Signed-off-by:. No Link: https://patch.msgid.link/20261007-b4-skbuff-bug-on-v2-5-b9a5f732895b@toxicpanda.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-15net: skbuff: don't BUG() on leftover length in skb_checksum() and friendsJosef Bacik
skb_checksum(), skb_crc32c() and __skb_to_sgvec() walk the head, frags and frag_list and BUG() if they run out of skb before they run out of @len. By then nothing has been read past the end of the skb. The walk stopped at the end of the data, and the check only tells us the caller asked for a range the skb doesn't have. commit 06a0afcfe2f5 ("xfrm: do pskb_pull properly in __xfrm_transport_prep") fixed one such caller that crashed in __skb_to_sgvec(). Return what each function already returns when it can't do the work, with a DEBUG_NET_WARN_ON_ONCE() for debug kernels: - __skb_to_sgvec() returns -EINVAL. Every skb_to_sgvec() caller has checked for a negative return since it learned to return -EMSGSIZE. - skb_checksum() and skb_crc32c() return 0, as they already do for unreadable frags. The resulting checksum is wrong, so the packet fails verification on receive or goes out with a bad checksum on transmit, rather than taking the machine down. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Link: https://patch.msgid.link/20261007-b4-skbuff-bug-on-v2-4-b9a5f732895b@toxicpanda.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-15net: skbuff: don't BUG() when skb_copy_bits() fails in copy helpersJosef Bacik
skb_copy(), skb_copy_expand() and skb_try_coalesce() all BUG() if skb_copy_bits() fails. skb_copy_bits() only fails when the skb's lengths don't add up, which is a bug somewhere else, usually in a driver building the skb. Each of these functions already has a failure return its callers handle: - skb_copy() and skb_copy_expand() free the new skb and return NULL, as they do when the allocation fails. - skb_try_coalesce() returns false and the caller keeps the skbs separate. Copy into the tailroom before skb_put() so that @to is untouched on failure. Take those returns, with a DEBUG_NET_WARN_ON_ONCE() for debug kernels. __pskb_pull_tail() has the same BUG_ON(), but several of its callers can't otherwise fail and don't check its return, so it's left for a separate change that fixes them first. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Link: https://patch.msgid.link/20261007-b4-skbuff-bug-on-v2-3-b9a5f732895b@toxicpanda.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-15net: skbuff: don't BUG() on a bad frag_list layout in skb_segment()Josef Bacik
skb_segment()'s frag_list walk assumes the GRO-shaped layout it expects and BUG()s when the layout doesn't match. Anybody who can get a malformed GSO skb to a segmentation point gets to crash the box. Most recently commit d5dc1e69fd72 ("inet: frags: strip GSO state from fragments before reassembly") fixed one that an unprivileged user could trigger with two writes to a tap device in their own user namespace. commit 3382a1ed7f77 ("net: fix udp gso skb_segment after pull from frag_list") fixed another. skb_segment() already has an error path for a bad layout: the too-many-frags check sets -EINVAL and frees the partial segment list. Take that path for the four layout checks, with a DEBUG_NET_WARN_ON_ONCE() for debug kernels. The packet gets dropped, which is what should happen to a packet we can't segment. The one check that runs after skb_clone() and before the clone is linked into the segment list frees the clone itself. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Link: https://patch.msgid.link/20261007-b4-skbuff-bug-on-v2-2-b9a5f732895b@toxicpanda.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-15net: skbuff: don't BUG() on bad arguments to pskb_expand_head()Josef Bacik
pskb_expand_head() BUG()s if it is handed a negative nhead or a shared skb. Both are bugs in the caller, and both keep getting hit: commit 2cbb259ec4f8 ("bpf: Reject negative head_room in __bpf_skb_change_head") and commit 64e6a754d33d ("llc: do not use skb_get() before dev_queue_xmit()") each fixed a crash here that took down the whole box. The function already returns an error that every caller has to handle, and at this point it hasn't touched the skb. Return -EINVAL instead of crashing. The warning is DEBUG_NET_WARN_ON_ONCE(), so debug kernels still point at the caller, while production kernels, including ones running with panic_on_warn, just fail the call. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Link: https://patch.msgid.link/20261007-b4-skbuff-bug-on-v2-1-b9a5f732895b@toxicpanda.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-15net: netmem: document netmem and memory provider design in commentsMina Almasry
Clarify the netmem, memory provider, page_pool, and skb fragment design principles in header and code comments: - Memory providers allocate struct net_iov or struct page, cast them to netmem_ref, and pass them to page_pool; page_pool, drivers, and the core stack operate on netmem_ref and must not downcast to page or net_iov outside dedicated netmem helpers. - While current memory providers supply struct net_iov, they are not architecturally restricted to net_iov and may supply page-backed netmems. - While current net_iov types are CPU-unreadable, net_iov has no inherent restrictions and may be readable or unreadable. - New code should generalize existing limitations as much as possible to match these design principles. - Per-provider logic belongs in memory_provider_ops, and per-netmem-type logic belongs in netmem helpers. - All frags in an skb must either all be struct page-backed or all belong to the same memory provider instance; mixing them (including via coalescing) is not allowed. Cc: Luigi Rizzo <lrizzo@google.com> Cc: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Mina Almasry <almasrymina@google.com> Acked-by: Jesper Dangaard Brouer <hawk@kernel.org> Reviewed-by: Björn Töpel <bjorn@kernel.org> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20261010033630.1171692-2-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-13net: gso: clear the GSO state of the last output segmentWang Zhan
skb_segment() clears gso_size on the last output of a group which holds one MSS or less, but leaves gso_segs and gso_type as the grouping set them, so the tail is still counted as the whole group. Readers which take gso_segs without testing gso_size first, such as the ECT statistics in ip_rcv_core() and tp->rcv_ooopack in tcp_rcv_established(), see that stale count, and a re-segmented output reaches them when a veth or bridge port delivers it back into the receive path. Clear gso_size, gso_segs and gso_type together with skb_gso_reset(). Suggested-by: Willem de Bruijn <willemb@google.com> Assisted-by: LLM Signed-off-by: Wang Zhan <wang.zhan@smartx.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20261008100651.2534957-5-wang.zhan@smartx.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-13net: gso: support re-segmentation of TCP GSO skbsWang Zhan
A caller which re-segments an oversized TCP GSO skb needs the engine to group several MSS into one output skb, so let it pass how many MSS segments each output skb may carry through __skb_gso_segment(). max_segs is a per-call u8 in the skb_gso_cb scratch context, and only an unencapsulated TCP skb without a frag_list sets it; every other caller passes zero. Without max_segs, skb_segment() groups several MSS into one output skb only for a device which advertises NETIF_F_GSO_PARTIAL, or for a frag_list which splits into uniform pieces. max_segs skips that test. The output stays a GSO skb: gso_size keeps the original MSS and gso_segs the number of MSS it holds, so a downstream device can still perform TSO. The caller keeps the output within the 64 KiB its L3 length field can express. Reviewed-by: Willem de Bruijn <willemb@google.com> Assisted-by: LLM Signed-off-by: Wang Zhan <wang.zhan@smartx.com> Link: https://patch.msgid.link/20261008100651.2534957-4-wang.zhan@smartx.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-08Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.3-rc7). Conflicts: include/net/strparser.h 0984ebc631792 ("strparser: make sure __strp_recv isn't running before tearing down the parser") 02fd0a2111374 ("net: strparser: removed the aborted bit and aborts counter") https://lore.kernel.org/asYfmLsfy-SCxXjr@sirena.co.uk Adjacent changes: Documentation/networking/strparser.rst 5f193cdabf25 ("docs: networking: strparser: remove general mode") 0984ebc63179 ("strparser: make sure __strp_recv isn't running before tearing down the parser") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-08net: skbuff: don't leave stale bytes in skb_copy_and_csum_bits()Josef Bacik
When skb_copy_and_csum_bits() reaches unreadable frags it returns 0 after copying only the linear part, and the rest of the caller's buffer is left as it was. The callers copy into a buffer that is about to go out on the wire: an ICMP error quoting the offending packet, or a driver's TX bounce buffer in skb_copy_and_csum_dev(). Neither buffer is zeroed beforehand, so whatever was in memory there gets sent. Zero the part of the buffer we didn't fill. The checksum usually won't match the data any more, so the receiver will usually drop the packet, but either way it no longer carries anything it shouldn't. Only zero for a positive @len, a negative one from a broken caller must not turn into a huge memset(). Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags") Cc: stable@vger.kernel.org Signed-off-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261007-b4-skb-copy-csum-stale-bytes-v1-1-adbbde033fb3@toxicpanda.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-05net: remove IPX raw 802.3 detection from eth_type_trans()Eric Dumazet
eth_type_trans() and vlan_set_encap_proto() still carry a "magic hack" to spot Novell raw 802.3 frames (IPX directly over 802.3, without an 802.2 LLC header) by looking for 0xFFFF in the first two bytes of the payload, and report them as ETH_P_802_3. IPX was removed in commit 7a2e838d28cf ("staging: ipx: delete it from the tree") and there is no in-kernel packet handler for ETH_P_802_3 on the Ethernet receive path anymore. Simply classify all frames using a length field as ETH_P_802_2, which is what the remaining LLC users (STP, GARP, SNAP) register for. This removes a skb_header_pointer() call (and the skb->dev scratch trick used to avoid a stack canary) from eth_type_trans(), and lets skb_vlan_untag() only pull VLAN_HLEN bytes, as the extra two bytes were only needed for this check since commit 55eff0eb7460 ("net: Fix potential wrong skb->protocol in skb_vlan_untag()"). Note that such frames are now reported to AF_PACKET, tc, BPF and nftables with skb->protocol == ETH_P_802_2 instead of ETH_P_802_3. $ scripts/bloat-o-meter -t vmlinux.old vmlinux.new add/remove: 0/0 grow/shrink: 2/5 up/down: 33/-187 (-154) Function old new delta skb_shift 1736 1768 +32 eth_type_trans.cold 45 46 +1 skb_vlan_untag 690 678 -12 __skb_vlan_pop 489 477 -12 nf_flow_encap_pop 462 449 -13 eth_type_trans 354 220 -134 Total: Before=31212910, After=31212756, chg -0.00% Signed-off-by: Eric Dumazet <edumazet@kernel.org> Link: https://patch.msgid.link/20261002185509.17226-1-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.3-rc6). Conflicts: net/mac80211/tx.c net/mac80211/ieee80211_i.h 8effab902fa34 ("wifi: mac80211: prevent AP VLAN tx from other interfaces") 78b843974fb83 ("wifi: mac80211: report multicast transmission from lookup_ra_sta()") https://lore.kernel.org/arJmcuhpJ69wAvYK@sirena.co.uk drivers/net/ethernet/realtek/r8169_main.c 3cdeaef1754ab ("r8169: disable EEE on RTL8168h/8111h") 8a3c76523e449 ("r8169: add support for phylink") https://lore.kernel.org/ar5vAxEqS8tO8aVT@sirena.org.uk Adjacent changes: rust/kernel/net/netlink.rs 5e5916923759 ("rust: net: netlink: Migrate to zerocopy's IntoBytes") 0923198be4ae ("rust: net: netlink: validate attribute length before casting to `c_int`") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-29net: fix checksum offsets in skb_splice_from_iter()Alireza Asgari
skb_splice_from_iter() appends multiple page fragments before updating skb->len. However, skb_splice_csum_page() uses that unchanged length as the offset for every fragment checksum. If bytes already appended during the call have an odd total length, a later fragment's checksum is combined with the wrong parity. For example, prime a UDP socket with sendto(MSG_MORE) and splice two distinct pipe buffers containing "abc" and "DEFGH". Uncorking reports success, but the receiver discards the packet for a bad checksum. This also affects IPv6 and fragments beginning near a page boundary. Pass the initial skb length plus the bytes already spliced to the checksum helper. Keep the existing final length update and partial-progress error handling unchanged. CHECKSUM_PARTIAL does not use this helper and remains unaffected. Fixes: 2e910b95329c ("net: Add a function to splice pages into an skbuff for MSG_SPLICE_PAGES") Cc: stable@vger.kernel.org Signed-off-by: Alireza Asgari <alireza@asgari.net> Link: https://patch.msgid.link/20260924-fix-udp-splice-checksum-v1-1-fe61d65447a8@asgari.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-24Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.3-rc5). Conflicts: drivers/net/mdio/mdio-realtek-rtl9300.c 89a8a1eef2d44 ("net: mdio: realtek-rtl9300: fix RTL931x C22 extended page selection") cc3cb8db1eef9 ("net: mdio: realtek-rtl9300: Add page tracking") https://lore.kernel.org/arUZOqy73bE2pp0w@sirena.org.uk net/8021q/vlan_dev.c cd5dd68267c4 ("vlan: ensure sufficient headroom in vlan_dev_hard_header()") ca6ff8dd70eb ("vlan: annotate data-races in vlan_dev_priv fields") Adjacent changes: net/ipv6/ip6_gre.c dd47bcf279f1 ("ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink().") cce829e2aa1d ("ip6_gre: Protect ip6gre_net.tunnels[][] with mutex.") drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b5d9e9d4d0c1 ("eth: fbnic: use the Rx queue napi pointer to find the napi vector") c0aca269ec07 ("eth: fbnic: Make Rx completion coalescing configurable") drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c d68acbf93531 ("net: stmmac: selftests: Support running selftests on DSA conduits") 85ca3292d7a3 ("net: stmmac: Remove ARP offload code") drivers/net/ethernet/wangxun/libwx/wx_hw.c 3173cba11701 ("net: libwx: fix races in Tx timestamp handling") 7042c8c193e5 ("net: libwx: rename wx_pf_flags to wx_flags") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-24net: flush skb_defer_nodes in dev_cpu_dead()Eric Dumazet
When a CPU goes offline, dev_cpu_dead() drains its softnet queues (completion_queue, output_queue, poll_list, process_queue, and input_pkt_queue), but leaves net_hotdata.skb_defer_nodes untouched. If oldcpu goes offline while holding pending skbs in its skb_defer_nodes lists (e.g. below the sysctl_skb_defer_max >> 1 IPI threshold, or if the IPI races with CPU teardown), those skbs remain stranded until oldcpu is brought back online. If any of these skbs hold page_pool fragments, page_pool_destroy() will stall indefinitely waiting for inflight pages to be returned when a netdev or driver is torn down while oldcpu is offline. Additionally, if smp_call_function_single_async() fails in kick_defer_list_purge() because the target CPU went offline, reset defer_ipi_scheduled to 0 so future IPI kicks are not blocked when the CPU comes back online. Also, if oldcpu was the last online CPU on its NUMA node, drain that node's slot across all CPUs so no skbs deferred from that node remain stranded on idle remote CPUs (or if the node itself is subsequently offlined). Finally, in skb_attempt_defer_free(), re-check cpu_online(cpu) and whether the caller migrated CPUs after llist_add(), flushing the node list if so, to close the preemption TOCTOU race against CPU/node teardown. Fixes: 68822bdf76f1 ("net: generalize skb freeing deferral to per-cpu lists") Fixes: 5628f3fe3b16 ("net: add NUMA awareness to skb_attempt_defer_free()") Closes: https://lore.kernel.org/netdev/20260916003430.3612956-1-kris.pan@intel.com/ Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Kris Pan <kris.pan@intel.com> Link: https://patch.msgid.link/20260923130318.607255-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-23net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6()Shihuang Liu
skb_maybe_pull_tail() subtracts skb_headlen(skb) from the unsigned max argument and passes the result to __pskb_pull_tail() as a signed int. The function does not ensure that max is at least skb_headlen(skb). This can happen while parsing IPv6 extension headers when an skb already has a linear area larger than MAX_IPV6_HDR_LEN. Once the parser needs data beyond the linear area, max - skb_headlen(skb) wraps and is converted to a negative delta. __pskb_pull_tail() then passes that negative length to skb_copy_bits(), where it can become a very large copy length. Pass the requested length itself as the pull bound at the three extension-header call sites, so the delta can no longer go negative. Fixes: 1431fb31ecba ("xen-netback: fix fragment detection in checksum setup") Suggested-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Shihuang Liu <shlomojune6@gmail.com> Link: https://patch.msgid.link/20260919133604.50948-1-shlomojune6@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-17Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.3-rc4). Conflicts: net/core/neighbour.c 979aabdad8dd0 ("neighbour: Skip default parms when resumed in neightbl_dump_info().") 7b430fcfc972f ("neighbour: Don't render blackhole_netdev via RTM_GETNEIGHTBL.") fae1c59810b86 ("neighbour: Remove unnecessary net_eq().") https://lore.kernel.org/20260911173056.44ec06e0@kernel.org https://lore.kernel.org/aqfbJi7nAX4IbmnR@sirena.co.uk Adjacent changes: net/netlink/af_netlink.c ceac0de741bf ("netlink: do not free nlk->groups while lockless readers can use it") 7c0ec6288b49 ("net: Replace %pK output with 0") net/bridge/br_vlan.c 2842ce397dd0 ("net: bridge: vlan: fix bugs caused by switchdev deletion errors") 5bec8f861114 ("net: bridge: vlan: annotate lockless use of num_vlans") 2b1f8fd3118c ("net: bridge: vlan: annotate lockless vlan flags use") net/bridge/br_mst.c 18a6fe05fb6e ("net: bridge: mst: move switchdev call outside rcu") 120207a08fc0 ("net: bridge: vlan: annotate lockless use of msti") drivers/net/ethernet/stmicro/stmmac/hwif.h 90e4b849dfa6 ("net: stmmac: propagate FPE preemption-class mapping errors") 85ca3292d7a3 ("net: stmmac: Remove ARP offload code") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-17net: skbuff: do not leave stale header offsets after pskb_carve()Eric Dumazet
pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove the first bytes of a packet and reallocate skb->head. All the headers that were present before the operation are gone, but both functions call skb_headers_offset_update(skb, 0), which is a no-op : skb->mac_header, skb->network_header, skb->transport_header and skb->csum_start keep their old values and now describe bytes which are no longer there. Both helpers size the new head from the old skb_end_offset(), so the stale offsets still land inside the new allocation. They point past skb_tail_pointer() though, to bytes that were never initialized. pskb_carve_inside_nonlinear() is the worst case, because it leaves a zombie skb with an empty linear part (skb->data == skb_tail_pointer(skb), skb_headlen(skb) == 0), while skb_mac_header_was_set() is still true and skb->mac_header is way ahead of skb->data. The only user of pskb_extract() is rds_tcp_data_recv(), and the carved skb is queued on tinc->ti_skb_list. When the RDS incoming message is released, rds_tcp_inc_free() calls skb_queue_purge(), which frees the skbs with SKB_DROP_REASON_QUEUE_PURGE. This is visible from drop_monitor, which then tries to pull back to the (bogus) mac header : skbuff: __skb_pull(len=234) skb len=6968 data_len=6968 headroom=0 headlen=0 tailroom=0 end-tail=384 mac=(234,14) mac_len=14 net=(248,40) trans=288 shinfo(txflags=0 nr_frags=1 gso(size=1428 type=16 segs=5)) csum(0x100120 start=288 offset=16 ip_summed=3 complete_sw=0 valid=1 level=0) hash(0x7b446c6c sw=0 l4=1) proto=0x86dd pkttype=0 iif=60 kernel BUG at ./include/linux/skbuff.h:2847! Add skb_carve_reset_headers() to mark the mac and transport headers as not set, reset the network header, clear skb->mac_len, and drop a now meaningless CHECKSUM_PARTIAL (csum_start no longer describes anything). Invalidate the inner offsets as well. Unlike mac_header and transport_header they have no "unset" sentinel, so a leftover non-zero value still looks like a real header. Zero skb->inner_mac_header, skb->inner_network_header, skb->inner_transport_header, skb->inner_protocol and skb->encapsulation, so that all the header state is invalidated in one place. v2: fixed an inaccurate changelog. The stale offsets stay inside the new skb->head, which is never smaller than the old one, they simply point past skb_tail_pointer() to bytes that are gone. Thanks to Xuanqiang Luo for insisting on this. Also invalidate the inner header state, as suggested by the netdev AI review : https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260911114922.621937-1-edumazet%40google.com Fixes: 6fa01ccd8830 ("skbuff: Add pskb_extract() helper function") Reported-by: syzbot+586af68eb819833c2d91@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6aa3e9d3.f2639fcc.29487d.0028.GAE@google.com/ Cc: Xuanqiang Luo <xuanqiang.luo@linux.dev> Cc: Allison Henderson <achender@kernel.org> Cc: rds-devel@oss.oracle.com Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn> Link: https://patch.msgid.link/20260915130423.3956471-1-edumazet@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-09-10Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.3-rc3). Conflicts: drivers/net/dsa/mt7530.c 3c18e3c9a54e ("net: dsa: mt7530: populate lpi_interfaces to fix EEE support") 10d9d8328e8a ("net: dsa: mt7530: replace mt7530_read with regmap_read") Adjacent changes: drivers/net/bonding/bond_alb.c 1746ef2e2df2 ("bonding: use skb_cow_head() in bond_do_alb_xmit() and rlb_arp_xmit()") 4cef95f72bbd ("bonding: fix u32 overflow in compute_gap()") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-04net: mpls: clear inner_protocol when the last label is poppedFourie Zhang
skb_mpls_push() records the pre-encapsulation network header once, gated on !skb->inner_protocol. skb_mpls_pop() never clears that record, so it outlives the encapsulation it describes. Open vSwitch can then re-push MPLS onto a packet whose inner_network_header still points at the older, deeper offset: push a label, pop every label, recirculate (ovs_flow_key_update() re-derives key->eth.type and resets network_header, but leaves inner_*), then push again. ovs_fragment() trusts the record: skb->network_header = skb->inner_network_header; so skb_network_offset() goes negative. The bound check is signed: if (skb_network_offset(skb) > MAX_L2_LEN) a negative offset passes it, and prepare_frag() widens the value: unsigned int hlen = skb_network_offset(skb); memcpy(&data->l2_data, skb->data, hlen); which is a ~4GiB memcpy out of a 30-byte per-CPU buffer. Reproduced on v7.3-rc1. RDX is the truncated length, (unsigned int)(-8): BUG: unable to handle page fault for address: ffffe8ffffc16000 #PF: supervisor write access in kernel mode Oops: 0002 [#1] SMP KASAN NOPTI RIP: 0010:memcpy+0x8/0x20 RDX: 00000000fffffff8 RSI: ffff888105d732db RDI: ffffe8ffffc16000 prepare_frag+0x3df/0x4e0 ovs_fragment+0x589/0x7e0 do_output+0x4ce/0x5e0 do_execute_actions+0x55d2/0x7b30 ovs_execute_actions+0xea/0x450 Same root-cause shape as commit 975b5b067f52 ("ipv6: sr: restore network header before routing and forwarding"): a stale network header offset reaching a consumer that widens it. Here it originates in the MPLS push/pop path. Clear inner_protocol once the packet is no longer MPLS, so a later push re-records the current header. net/sched/act_mpls.c is the only other skb_mpls_pop() caller and gets the same fix; sch_frag.c saves and restores inner_protocol around fragmentation in the same way OVS does. Fixes: 48d2ab609b6b ("net: mpls: Fixups for GSO") Cc: stable@vger.kernel.org Signed-off-by: Fourie Zhang <fouriezhang@tencent.com> Acked-by: Jiri Benc <jbenc@redhat.com> Link: https://patch.msgid.link/20260902092719.2874481-1-fouriezhang@tencent.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-01net: Make skb_ext_put_mctp() idempotentJakub Sitnicki
The MCTP flow extension can be released either when it is deleted from an skb or when the last skb holding the extension block is freed. Handle the release in __skb_ext_del(), which is currently missing, and make skb_ext_put_mctp() safe to call from both paths. This will let __skb_ext_put() release the MCTP key without checking whether the extension is present first, which is needed if we want to reuse skb_ext chunks area after skb scrubbing. Suggested-by: Florian Westphal <fw@strlen.de> Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com> Acked-by: Jeremy Kerr <jk@codeconstruct.com.au> Link: https://patch.msgid.link/20260831-skb-ext-prep-work-v1-2-ecc2a8542fd9@cloudflare.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-01net: Make skb_ext_put_sp() idempotentJakub Sitnicki
The sec_path extension can be released either when it is deleted from an skb or when the last skb holding the extension block is freed. Make skb_ext_put_sp() safe to call from both paths by returning when sec_path->len is zero and clearing it after dropping the XFRM state references. This will let __skb_ext_put() release the sec_path without checking whether the extension is present first, which is needed if we want to reuse skb_ext chunks area after skb scrubbing. Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com> Link: https://patch.msgid.link/20260831-skb-ext-prep-work-v1-1-ecc2a8542fd9@cloudflare.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-27net: Guard for gso_segs overflow in skb_segmentAlice Mikityanska
skb_segment calculates 32-bit partial_segs as len / gso_size, and then assigns it to the 16-bit gso_segs field. The division might overflow in some edge cases where the SKB is BIG TCP (65536 <= len <= 8*65535), and gso_size < TCP_MIN_GSO_SIZE = 8. While normally this can't happen due to TCP_MIN_GSO_SIZE, an AF_PACKET PACKET_VNET_HDR socket could generate such a malformed packet until the previous patch. Blocking malformed virtio_net packets was implemented in the previous patch, but this patch clamps partial_segs in skb_segment itself for more generic robustness. Should len / gso_size happen to be bigger than 65535 in partial GSO, skb_segment will now just produce more than two output SKBs, all of which will be valid with gso_segs <= 65535. In order to catch possible other cases of too many partial_segs, add a DEBUG_NET_WARN_ON_ONCE when len / gso_size happens to be too big. Signed-off-by: Alice Mikityanska <alice@isovalent.com> Link: https://patch.msgid.link/20260822120117.1163423-3-alice.kernel@fastmail.im Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-25net: core: fix head-page leak in skb_zerocopyMina Almasry
When skb_orphan_frags() throws -ENOMEM, skb_copy_ubufs() may have already reallocated and replaced 'from->head'. Accessing from->head to drop the old refcount leaks the original head page, and erroneously puts an unrelated new buffer. Use the local 'page' tracker variable instead to drop the reference properly. Fixes: 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors") Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20260823183602.1051453-2-almasrymina@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-25net: core: check skb_frags_readable before uncloning in skb_copy_ubufsMina Almasry
skb_copy_ubufs drops clones and modifies the SKB via pskb_expand_head() before checking for !skb_frags_readable(skb). This alters the SKB geometry prior to throwing an -EFAULT on an invalid SKB. Check readability first. Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags") Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20260823183602.1051453-1-almasrymina@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-25net: skbuff: don't touch shared zerocopy state in skb_tx_error()Norbert Szetei
skb_tx_error() completes the zerocopy uarg and clears SKBFL_ALL_ZEROCOPY, and skb_zcopy_downgrade_managed() clears SKBFL_MANAGED_FRAG_REFS. Both live in skb_shinfo(), which every clone shares, while the caller only owns the reference it is about to drop. Through a clone it tells the producer its pages are free and drops SKBFL_SHARED_FRAG for an skb that is still in flight. Open vSwitch reaches this with a non-last OVS_ACTION_ATTR_RECIRC: clone_execute() sends a skb_clone() into ovs_dp_process_packet() while do_execute_actions() keeps forwarding the original, and skb_clone() does not privatise the frags here -- skb_orphan_frags() returns early on SKBFL_DONT_ORPHAN. A flow miss on the clone then strips the marker from the packet still being forwarded, and a later local ESP delivery decrypts in place over frags it does not own privately. Skip it for a cloned skb. Nothing is lost: skb_release_data() clears the zerocopy state once the last reference to the shared data goes. Fixes: 25121173f7b1 ("skb: api to report errors for zero copy skbs") Cc: stable@vger.kernel.org Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Tested-by: Jongmin Jang <payload.jang@gmail.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/CFAB292A-674B-4C14-BB2C-BB8830AD5659@doyensec.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-25net: skbuff: don't skb_tx_error() the source skb in skb_zerocopy()Norbert Szetei
skb_zerocopy() copies frags from @from into @to. On an skb_orphan_frags() failure it calls skb_tx_error(@from), a destructive operation on the source skb the copy helper does not own. That completes @from's zerocopy uarg and clears SKBFL_ALL_ZEROCOPY, including the SKBFL_SHARED_FRAG page-ownership marker. Both callers already report the failure on their own drop path. nfnetlink_queue does it at nla_put_failure, and Open vSwitch does it in the flow-miss drop arm of ovs_dp_process_packet(), so nothing is lost by dropping it here. On Open vSwitch's OVS_ACTION_ATTR_USERSPACE path the skb is not freed on this error: do_execute_actions() ignores output_userspace()'s return value and, unless the upcall was the last action, keeps forwarding the same skb through the flow's remaining actions. The uarg is completed while that skb is still in flight, telling the producer its buffers are free, and SKBFL_SHARED_FRAG is cleared on an skb the rest of the stack still handles. That flag is what makes esp_input() call skb_cow_data() instead of decrypting in place, so a later local ESP delivery can decrypt over frags the skb does not own privately. Leave error reporting to the callers. Fixes: 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors") Cc: stable@vger.kernel.org Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/6E3A780D-FB87-421F-9964-B1D457D7D106@doyensec.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-20net: core: propagate unreadable flag in skb_zerocopyMina Almasry
skb_zerocopy() fails to propagate the unreadable flag when copying unreadable fragments, causing target skbs to appear as readable memory. This patch fixes the flag propagation. Additionally, it returns -EFAULT if readable fragments are mixed with unreadable fragments during extraction, and returns -EFAULT in openvswitch queue_userspace_packet(). Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags") Cc: Stanislav Fomichev <sdf@fomichev.me> Cc: Bobby Eshleman <bobbyeshleman@gmail.com> Cc: Florian Westphal <fw@strlen.de> Cc: Aaron Conole <aconole@redhat.com> Cc: Eelco Chaudron <echaudro@redhat.com> Cc: Willem de Bruijn <willemb@google.com> Signed-off-by: Mina Almasry <almasrymina@google.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Link: https://patch.msgid.link/20260814191336.187243-1-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-30Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.2-rc6). No conflicts. Adjacent changes: net/ipv4/route.c dbc3791e3b24 ("net: do not send ICMP/NDISC Redirects when peer allocation fails") 7804eaa057fe ("ipv4: snapshot dst.dev in ip_rt_send_redirect() and ip_rt_get_source()") drivers/net/tun.c 23dad2d088df ("tun: no longer rely on RTNL in tun_fill_info()") c3da92af07ea ("Revert "tun/tap: add ptr_ring consume helper with netdev queue wakeup"") drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c 3bd438a58e91 ("octeontx2-af: Block VFs from clobbering special CGX PKIND state") 5ba5611ef946 ("octeontx2-af: reserve 4 PKINDs for skip-size custom use") drivers/net/wireless/ath/ath12k/core.h drivers/net/wireless/ath/ath12k/mac.c drivers/net/wireless/ath/ath12k/peer.c 469d7e6077c1 ("wifi: ath12k: resolve PENDING ML peer ID from MLO_PEER_MAP HTT event") 378e659029d5 ("wifi: ath12k: introduce host_alloc_ml_id hardware parameter") c42b27336eef ("wifi: ath12k: fix survey indexing across bands") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-24veth: convert frag_list skbs before running XDPMatt Fleming
A frag_list skb can reach veth with data_len set but nr_frags zero. veth_convert_skb_to_xdp_buff() only converts skbs that are shared, locked, have frags[], or do not have enough headroom. It later uses skb_is_nonlinear() to decide whether to set XDP_FLAGS_HAS_FRAGS and xdp_frags_size. That exposes frag_list data to XDP as if it were stored in frags[], but frags[] is empty. AF_XDP copy mode can then trust the bogus XDP fragment metadata, walk an empty fragment entry, and crash in memcpy() from __xsk_rcv(). Route non-linear skbs through skb_pp_cow_data() before exposing them to XDP, and only advertise XDP frags when the resulting skb has frags[]. skb_copy_bits() already handles frag_list input, and skb_pp_cow_data() builds frags[] output with skb_add_rx_frag(), which is the representation XDP multi-buffer expects. Fixes: 718a18a0c8a6 ("veth: Rework veth_xdp_rcv_skb in order to accept non-linear skb") Cc: stable@vger.kernel.org Signed-off-by: Matt Fleming <mfleming@cloudflare.com> Reviewed-by: Toke Høiland-Jørgensen <toke@toke.dk> Acked-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://patch.msgid.link/20260722191925.2192070-1-matt@readmodwrite.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-22Merge branch 'big-tcp-for-udp-tunnels'Paolo Abeni
Alice Mikityanska says: ==================== BIG TCP for UDP tunnels This series is a follow-up to "BIG TCP without HBH in IPv6", and it adds support for BIG TCP IPv4/IPv6 workloads in vxlan and geneve. Now that IPv6 BIG TCP doesn't require stripping the HBH in all various combinations in tunneled traffic, adding BIG TCP becomes feasible. Patch 01 adds accessors for the length field in the UDP header, as suggested by Paolo in review. The usage of udp_set_len is then added in the following patches that start using length=0 in BIG TCP UDP packets. Patches 02-04 close the gaps that prevent BIG TCP packets from going through UDP tunnel code. Patch 05 validates packets in udp_gro_receive to exclude packets with length=0 from GRO aggregation. Patch 06 is for proper formatting in tcpdump (set UDP len to 0 rather than a trimmed value on overflow). Patches 07-08 bump up tso_max_size for VXLAN and GENEVE. Patch 09 adds selftests. ====================$ Link: https://patch.msgid.link/20260710134242.216538-1-alice.kernel@fastmail.im Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-22net: Enable BIG TCP with partial GSOAlice Mikityanska
skb_segment is called for partial GSO, when netif_needs_gso returns true in validate_xmit_skb. Partial GSO is needed, for example, when segmentation of tunneled traffic is offloaded to a NIC that only supports inner checksum offload. Currently, skb_segment clamps the segment length to 65534 bytes, because gso_size == 65535 is a special value GSO_BY_FRAGS, and we don't want to accidentally assign mss = 65535, as it would fall into the GSO_BY_FRAGS check further in the function. This implementation, however, artificially blocks len > 65534, which is possible since the introduction of BIG TCP. To allow bigger lengths and avoid resegmentation of BIG TCP packets, store the gso_by_frags flag in the beginning and don't use a special value of mss for this purpose after mss was modified. Signed-off-by: Alice Mikityanska <alice@isovalent.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20260710134242.216538-3-alice.kernel@fastmail.im Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-21net: skbuff: optimization of net_zcopy_get() call in pskb_carve helpersYun Lu
Commit 98d0912e9f84 ("net: skbuff: fix missing zerocopy reference in pskb_carve helpers") introduced two calls of net_zcopy_get(skb_zcopy(skb)). In fact, skb_zcopy() has already been executed once before. When calling net_zcopy_get(), skb_zcopy() always returns skb_uarg(skb), which results in adding some unnecessary instructions in skb_zcopy. So, change these two calls to directly use skb_uarg(skb) instead of skb_zcopy. In addition, also use net_zcopy_get() instead of refcount_inc() in pskb_expand_head() for code consistency. No functional change intended. Signed-off-by: Yun Lu <luyun@kylinos.cn> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20260708055454.9167-1-luyun_611@163.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-06-17Merge tag 'net-next-7.2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next Pull networking updates from Jakub Kicinski: "Core & protocols: - Work on removing rtnl_lock protection throughout the stack continues. In this chapter: - don't use rtnl_lock for IPv6 multicast routing configuration - don't take rtnl_lock in ethtool for modern drivers - prepare Qdisc dump callbacks for rtnl_lock removal - Support dumping just ifindex + name of all interfaces, under RCU. It's a common operation for Netlink CLI tools (when translating names to ifindexes) and previously required full rtnl_lock. - Support dumping qdiscs and page pools for a specific netdev. Even tho user space wants a dump of all netdevs, most of the time, the OOO programming model results in repeating the dump for each netdev. Which, in absence of a cache, leads to a O(n^2) behavior. - Flush nexthops once on multi-nexthop removal (e.g. when device goes down), another O(n^2) -> O(n) improvement. - Rehash locally generated traffic to a different nexthop on retransmit timeout. - Honor oif when choosing nexthop for locally generated IPv6 traffic. - Convert TCP Auth Option to crypto library, and drop non-RFC algos. - Increase subflow limits in MPTCP to 64 and endpoint limit to 256. - Support MPTCP signaling of IPv6 address + port (ADD_ADDR). We need to selectively skip reporting of the standard TCP Timestamp option, because they won't fit into the header space together (12 + 30 > 40). - Support using bridge neighbor suppression, Duplicate Address Detection, Gratuitous ARP and unsolicited NA forwarding - in EVPN deployments, e.g. VXLAN fabrics (IPv4 and IPv6). - Improve link state reporting for upper netdevs (e.g. macvlan) over tunnel devices (again, mostly for EVPN deployments). - Support binding GENEVE tunnels to a local address. - Speed up UDP tunnel destruction (remove one synchronize_rcu()). - Support exponential field encoding in multicast (IGMPv3 and MLDv2). - Support attaching PSP crypto offload to containers (veth, netkit). - Add a new IPSec Netlink message XFRM_MSG_MIGRATE_STATE that allows migrating individual IPsec SAs independently of their policies. The existing XFRM_MSG_MIGRATE is tightly coupled to policy+SA migration, lacks SPI for unique SA identification, and cannot express reqid changes or migrate Transport mode selectors. The new interface identifies the SA via SPI and mark, supports reqid changes, address family changes, encap removal, and uses an atomic create+install flow under x->lock to prevent SN/IV reuse during AEAD SA migration. - Implement GRO/GSO support for PPPoE. - Convert sockopt callbacks in a number of protocols to iov_iter. Cross-tree stuff: - Remove support for Crypto TFM cloning (unblocked after the TCP Auth Option rework). This feature regressed performance for all crypto API users, since it changed crypto transformation objects into reference-counted objects. - Add FCrypt-PCBC implementation to rxrpc and remove it from the global crypto API as obsolete and insecure. Wireless: - Major rework of station bandwidth handling, fixing issues with lower capability than AP. - Cleanups for EMLSR spec issues (drafts differed). - More Neighbor Awareness Networking (Wi-Fi Aware) work (multicast, schedule improvements, multi-station etc.) - Some Ultra High Reliability (UHR) / IEEE 802.11bn (D1.4) work (e.g. non-primary channel access, UHR DBE support). - Fine Timing Measurement ranging (i.e. distance measurement) APIs. Netfilter: - Use per-rule hash initval in nf_conncount. This avoids unnecessary lock contention with short keys (e.g. conntrack zones) in different namespaces. - Various safety improvements, both in packet parsing and object lifetimes. Notably add refcounts to conntrack timeout policy. Deletions: - Remove TLS + sockmap integration. TLS wants to pin user pages to avoid a copy, and sockmap wants to write to the input stream. More work on this integration is clearly needed, and we can't find any users (original author admitted that they never deployed it). - Remove support for TLS offload with TCP Offload Engine (the far more common opportunistic offload is retained). The locking looks unfixable (driver sleeps under TCP spin locks) and people from the vendor that added this are AWOL. - Remove more ATM code, trying to leave behind only what PPPoATM needs, AAL5 and br2684 with permanent circuits. - Remove AppleTalk. Let it join hamradio in our out of tree protocol graveyard, I mean, repository. - Disable 32-bit x_tables compatibility (32bit binaries on 64bit kernel) interface in user namespaces. To be deleted completely, soon. - Remove 5/10 MHz support from cfg80211/mac80211. Drivers: - Software: - Support DEVMEM/DMABUF Tx over NETMEM_TX_NO_DMA devices (netkit) - bonding: add knob to strictly follow 802.3ad for link state - New drivers: - Alibaba Elastic Ethernet Adaptor (cloud vNIC). - NXP NETC switch within i.MX94. - DPLL: - Add operational state to pins (implement in zl3073x). - Add generic DPLL type, for daisy-chaining DPLLs (implement in ice). - Ethernet high-speed NICs: - Huawei (hinic3): - enhance tc flow offload support with queue selection, tunnels - nVidia/Mellanox: - avoid over-copying payload to the skb's linear part (up to 60% win for LRO on slow CPUs like ARM64 V2) - expose more per-queue stats over the standard API - support additional, unprivileged PFs in the DPU configuration - support Socket Direct (multi-PF) with switchdev offloads - add a pool / frag allocator for DMA mapped buffers for control objects, save memory on systems with 64kB page size - take advantage of the ability to dynamically change RSS table size, even when table is configured by the user - increase the max RSS table size for even traffic distribution - Ethernet NICs: - Marvell/Aquantia: - AQC113 PTP support - Realtek USB (r8152): - support 10Gbit Link Speeds and Energy-Efficient Ethernet (EEE) - support firmware loaded (for RTL8157/RTL8159) - support for the RTL8159 - Intel (ixgbe): - support Energy-Efficient Ethernet (EEE) on E610 devices - Ethernet switches: - Airoha: - support multiple netdevs on a single GDM block / port - Marvell (mv88e6xxx): - support SERDES of mv88e6321 - Microchip (ksz8/9): - rework the driver callbacks to remove one indirection layer - Motorcomm (yt921x): - support port rate policing - support TBF qdisc offload - support ACL/flower offload - nVidia/Mellanox: - expose per-PG rx_discards - Realtek: - rtl8365mb: bridge offloading and VLAN support - Ethernet PHYs: - Airoha: - support Airoha AN8801R Gigabit PHYs. - Micrel: - implement 3 low-loss cable tunables - Realtek: - support MDI swapping for RTL8226-CG - support MDIO for RTL931x - Qualcomm: - at803x: Rx and Tx clock management for IPQ5018 PHY - Motorcomm: - support YT8522 100M RMII PHY - set drive strength in YT8531s RGMII - TI: - dp83822: add optional external PHY clock - Bluetooth: - hci_sync: add support for HCI_LE_Set_Host_Feature [v2] - SMP: use AES-CMAC library API - Intel: - support Product level reset - support smart trigger dump - Mediatek: - add event filter to filter specific event - Realtek: - fix RTL8761B/BU broken LE extended scan - WiFi: - Broadcom (b43): - new support for a 11n device - MediaTek (mt76): - support mt7927 - mt792x: broken usb transport detection - mt7921: regulatory improvements - Qualcomm (ath9k): - GPIO interface improvements - Qualcomm (ath12k): - WDS support - replace dynamic memory allocation in WMI Rx path - thermal throttling/cooling device support - 6 GHz incumbent interference detection - channel 177 in 5 GHz - Realtek (rt89): - RTL8922AU support - USB 3 mode switch for performance - better monitor radiotap support - RTL8922DE preparations" * tag 'net-next-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1778 commits) ipv4: fib_rule: Move fib4_rules_exit() to ->exit(). net: serialize netif_running() check in enqueue_to_backlog() net: skmsg: preserve sg.copy across SG transforms appletalk: move the protocol out of tree appletalk: stop storing per-interface state in struct net_device selftests/bpf: test that TLS crypto is rejected on a sockmap socket selftests/bpf: drop the unused kTLS program from test_sockmap selftests/bpf: remove sockmap + ktls tests tls: remove dead sockmap (psock) handling from the SW path tls: reject the combination of TLS and sockmap atm: remove orphaned uAPI for deleted drivers, protocols and SVCs atm: remove unused ATM PHY operations atm: remove the unused pre_send and send_bh device operations atm: remove the unused change_qos device operation atm: remove SVC socket support and the signaling daemon interface atm: remove the local ATM (NSAP) address registry atm: remove dead SONET PHY ioctls atm: remove the unused send_oam / push_oam callbacks atm: remove AAL3/4 transport support net: dsa: sja1105: fix lastused timestamp in flower stats ...
2026-06-16Merge tag 'slab-for-7.2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab Pull slab updates from Vlastimil Babka: - Support for "allocation tokens" (currently available in Clang 22+) for smarter partitioning of kmalloc caches based on the allocated object type, which can be enabled instead of the "random" per-caller-address-hash partitioning. It should be able to deterministically separate types containing a pointer from those that do not (Marco Elver) - Improvements and simplification of the kmem_cache_alloc_bulk() and mempool_alloc_bulk() API. This includes adaptation of callers (Christoph Hellwig) - Performance improvements and cleanups related mostly to sheaves refill (Hao Li, Shengming Hu, Vlastimil Babka) - Several fixups for the slabinfo tool (Xuewen Wang) * tag 'slab-for-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab: mm/slab: do not limit zeroing to orig_size when only red zoning is enabled mm/slub: preserve original size in _kmalloc_nolock_noprof retry path mm: simplify the mempool_alloc_bulk API mm/slab: improve kmem_cache_alloc_bulk mm/slub: detach and reattach partial slabs in batch mm/slub: introduce helpers for node partial slab state mm/slub: use empty sheaf helpers for oversized sheaves tools/mm/slabinfo: remove redundant slab->partial assignment tools/mm/slabinfo: remove dead assignment in get_obj_and_str() tools/mm/slabinfo: Fix trace disable logic inversion MAINTAINERS: add slab-related scripts and tools to SLAB ALLOCATOR mm/slub: fix typo in sheaves comment mm, slab: simplify returning slab in __refill_objects_node() mm, slab: add an optimistic __slab_try_return_freelist() slab: fix kernel-docs for mm-api slab: improve KMALLOC_PARTITION_RANDOM randomness slab: support for compiler-assisted type-based slab cache partitioning mm/slub: defer freelist construction until after bulk allocation from a new slab
2026-06-11Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.1-rc8). Conflicts: drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c f67aead16e85 ("net: txgbe: rework service event handling") 57d39faed4c9 ("net: txgbe: improve functions of AML 40G devices") net/rds/info.c 512db8267b73 ("rds: mark snapshot pages dirty in rds_info_getsockopt()") 6e94eeb2a2a6 ("rds: convert to getsockopt_iter") Adjacent changes: include/net/sock.h 1ee90b77b727 ("net: guard timestamp cmsgs to real error queue skbs") f0de88303d5e ("net: make is_skb_wmem() available to modules") Signed-off-by: Jakub Kicinski <kuba@kernel.org>