Patch "net: gso: fix tcp fraglist segmentation after pull from frag_list" has been added to the 6.6-stable tree
gregkh at linuxfoundation.org
gregkh at linuxfoundation.org
Thu Mar 19 04:37:12 PDT 2026
This is a note to let you know that I've just added the patch titled
net: gso: fix tcp fraglist segmentation after pull from frag_list
to the 6.6-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
net-gso-fix-tcp-fraglist-segmentation-after-pull-from-frag_list.patch
and it can be found in the queue-6.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.
>From stable+bounces-222524-greg=kroah.com at vger.kernel.org Mon Mar 2 07:56:08 2026
From: Li hongliang <1468888505 at 139.com>
Date: Mon, 2 Mar 2026 14:55:22 +0800
Subject: net: gso: fix tcp fraglist segmentation after pull from frag_list
To: gregkh at linuxfoundation.org, stable at vger.kernel.org, nbd at nbd.name
Cc: patches at lists.linux.dev, linux-kernel at vger.kernel.org, edumazet at google.com, davem at davemloft.net, dsahern at kernel.org, kuba at kernel.org, pabeni at redhat.com, matthias.bgg at gmail.com, angelogioacchino.delregno at collabora.com, willemb at google.com, netdev at vger.kernel.org, linux-arm-kernel at lists.infradead.org, linux-mediatek at lists.infradead.org, bpf at vger.kernel.org
Message-ID: <20260302065522.2695626-1-1468888505 at 139.com>
From: Felix Fietkau <nbd at nbd.name>
[ Upstream commit 17bd3bd82f9f79f3feba15476c2b2c95a9b11ff8 ]
Detect tcp gso fraglist skbs with corrupted geometry (see below) and
pass these to skb_segment instead of skb_segment_list, as the first
can segment them correctly.
Valid SKB_GSO_FRAGLIST skbs
- consist of two or more segments
- the head_skb holds the protocol headers plus first gso_size
- one or more frag_list skbs hold exactly one segment
- all but the last must be gso_size
Optional datapath hooks such as NAT and BPF (bpf_skb_pull_data) can
modify these skbs, breaking these invariants.
In extreme cases they pull all data into skb linear. For TCP, this
causes a NULL ptr deref in __tcpv4_gso_segment_list_csum at
tcp_hdr(seg->next).
Detect invalid geometry due to pull, by checking head_skb size.
Don't just drop, as this may blackhole a destination. Convert to be
able to pass to regular skb_segment.
Approach and description based on a patch by Willem de Bruijn.
Link: https://lore.kernel.org/netdev/20240428142913.18666-1-shiming.cheng@mediatek.com/
Link: https://lore.kernel.org/netdev/20240922150450.3873767-1-willemdebruijn.kernel@gmail.com/
Fixes: bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets")
Cc: stable at vger.kernel.org
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Reviewed-by: Willem de Bruijn <willemb at google.com>
Link: https://patch.msgid.link/20240926085315.51524-1-nbd@nbd.name
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
Signed-off-by: Li hongliang <1468888505 at 139.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
net/ipv4/tcp_offload.c | 10 ++++++++--
net/ipv6/tcpv6_offload.c | 10 ++++++++--
2 files changed, 16 insertions(+), 4 deletions(-)
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -104,8 +104,14 @@ static struct sk_buff *tcp4_gso_segment(
if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
return ERR_PTR(-EINVAL);
- if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
- return __tcp4_gso_segment_list(skb, features);
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) {
+ struct tcphdr *th = tcp_hdr(skb);
+
+ if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size)
+ return __tcp4_gso_segment_list(skb, features);
+
+ skb->ip_summed = CHECKSUM_NONE;
+ }
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
const struct iphdr *iph = ip_hdr(skb);
--- a/net/ipv6/tcpv6_offload.c
+++ b/net/ipv6/tcpv6_offload.c
@@ -106,8 +106,14 @@ static struct sk_buff *tcp6_gso_segment(
if (!pskb_may_pull(skb, sizeof(*th)))
return ERR_PTR(-EINVAL);
- if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
- return __tcp6_gso_segment_list(skb, features);
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) {
+ struct tcphdr *th = tcp_hdr(skb);
+
+ if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size)
+ return __tcp6_gso_segment_list(skb, features);
+
+ skb->ip_summed = CHECKSUM_NONE;
+ }
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
Patches currently in stable-queue which might be from 1468888505 at 139.com are
queue-6.6/pnfs-fix-a-deadlock-when-returning-a-delegation-during-open.patch
queue-6.6/net-add-support-for-segmenting-tcp-fraglist-gso-packets.patch
queue-6.6/net-fix-segmentation-of-forwarding-fraglist-gro.patch
queue-6.6/nfs-pass-explicit-offset-count-to-trace-events.patch
queue-6.6/net-gso-fix-tcp-fraglist-segmentation-after-pull-from-frag_list.patch
queue-6.6/nfs-fix-a-deadlock-involving-nfs_release_folio.patch
More information about the Linux-mediatek
mailing list