* [PATCH net-next v2 0/2] Guard against gso_segs overflows @ 2026-08-13 17:46 Alice Mikityanska 2026-08-13 17:46 ` [PATCH net-next v2 1/2] net: Guard for gso_segs overflow in skb_segment Alice Mikityanska 2026-08-13 17:46 ` [PATCH net-next v2 2/2] virtio-net: Ensure that TCP packets don't overflow gso_segs Alice Mikityanska 0 siblings, 2 replies; 5+ messages in thread From: Alice Mikityanska @ 2026-08-13 17:46 UTC (permalink / raw) To: Paolo Abeni, Jakub Kicinski, Eric Dumazet, Michael S. Tsirkin, Jason Wang Cc: David S. Miller, Simon Horman, Xuan Zhuo, Eugenio Pérez, Jason Xing, Kuniyuki Iwashima, Björn Töpel, Jiayuan Chen, netdev, Alice Mikityanska From: Alice Mikityanska <alice@isovalent.com> This series is a follow-up on the discussion: https://lore.kernel.org/netdev/CAD0BsJWzSr2zduf5v3mVC4zd=Lj6ZAoC+V42-VBdg42aDY8XXw@mail.gmail.com/T/#m1e22fca273c36cc8844e516505d3251cc1418fea skb_segment is patched to avoid possible overflows in partial GSO. The primary possible source of too many GSO segments is also addressed: virtio-net clamps gso_size to >=8 in TCP, as suggested by Eric. v2 changes: dropped new checks in fastpath from skb_gro_receive and __virtio_net_hdr_to_skb, replaced the latter with a silent clamp for gso_size, kept the cheap guard in skb_segment. v1: https://lore.kernel.org/netdev/20260723155145.158572-1-alice.kernel@fastmail.im/ Alice Mikityanska (2): net: Guard for gso_segs overflow in skb_segment virtio-net: Ensure that TCP packets don't overflow gso_segs include/linux/virtio_net.h | 4 ++++ net/core/skbuff.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) -- 2.55.0 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net-next v2 1/2] net: Guard for gso_segs overflow in skb_segment 2026-08-13 17:46 [PATCH net-next v2 0/2] Guard against gso_segs overflows Alice Mikityanska @ 2026-08-13 17:46 ` Alice Mikityanska 2026-08-18 13:38 ` Paolo Abeni 2026-08-13 17:46 ` [PATCH net-next v2 2/2] virtio-net: Ensure that TCP packets don't overflow gso_segs Alice Mikityanska 1 sibling, 1 reply; 5+ messages in thread From: Alice Mikityanska @ 2026-08-13 17:46 UTC (permalink / raw) To: Paolo Abeni, Jakub Kicinski, Eric Dumazet, Michael S. Tsirkin, Jason Wang Cc: David S. Miller, Simon Horman, Xuan Zhuo, Eugenio Pérez, Jason Xing, Kuniyuki Iwashima, Björn Töpel, Jiayuan Chen, netdev, Alice Mikityanska From: Alice Mikityanska <alice@isovalent.com> 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 can generate such a malformed packet. Blocking malformed virtio_net packets is implemented in the next 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. Signed-off-by: Alice Mikityanska <alice@isovalent.com> --- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c82a1472a5ea..439cbfeb02bd 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4860,7 +4860,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, * doesn't fit into an MSS sized block, so take care of that * now. */ - partial_segs = len / mss; + partial_segs = min(len / mss, GSO_MAX_SEGS); if (partial_segs > 1) mss *= partial_segs; else -- 2.55.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net-next v2 1/2] net: Guard for gso_segs overflow in skb_segment 2026-08-13 17:46 ` [PATCH net-next v2 1/2] net: Guard for gso_segs overflow in skb_segment Alice Mikityanska @ 2026-08-18 13:38 ` Paolo Abeni 2026-08-19 17:18 ` Alice Mikityanska 0 siblings, 1 reply; 5+ messages in thread From: Paolo Abeni @ 2026-08-18 13:38 UTC (permalink / raw) To: Alice Mikityanska, Jakub Kicinski, Eric Dumazet, Michael S. Tsirkin, Jason Wang Cc: David S. Miller, Simon Horman, Xuan Zhuo, Eugenio Pérez, Jason Xing, Kuniyuki Iwashima, Björn Töpel, Jiayuan Chen, netdev, Alice Mikityanska On 8/13/26 7:46 PM, Alice Mikityanska wrote: > From: Alice Mikityanska <alice@isovalent.com> > > 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 can generate such > a malformed packet. > > Blocking malformed virtio_net packets is implemented in the next 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. Minor nit: I think it would make sense to re-order the patches. > Signed-off-by: Alice Mikityanska <alice@isovalent.com> > --- > net/core/skbuff.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/core/skbuff.c b/net/core/skbuff.c > index c82a1472a5ea..439cbfeb02bd 100644 > --- a/net/core/skbuff.c > +++ b/net/core/skbuff.c > @@ -4860,7 +4860,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, > * doesn't fit into an MSS sized block, so take care of that > * now. > */ > - partial_segs = len / mss; > + partial_segs = min(len / mss, GSO_MAX_SEGS); Since on top of patch 2/2 the min() should always be a no-op, what about instead: if (WARN_ON_ONCE(len/mss > GSO_MAX_SEGS)) return ERR_PTR(-EINVAL); ? /P ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next v2 1/2] net: Guard for gso_segs overflow in skb_segment 2026-08-18 13:38 ` Paolo Abeni @ 2026-08-19 17:18 ` Alice Mikityanska 0 siblings, 0 replies; 5+ messages in thread From: Alice Mikityanska @ 2026-08-19 17:18 UTC (permalink / raw) To: Paolo Abeni, Jakub Kicinski, Eric Dumazet, Michael S. Tsirkin, Jason Wang Cc: David S. Miller, Simon Horman, Xuan Zhuo, Eugenio Pérez, Jason Xing, Kuniyuki Iwashima, Björn Töpel, Jiayuan Chen, netdev, Alice Mikityanska On Tue, Aug 18, 2026, at 16:38, Paolo Abeni wrote: > On 8/13/26 7:46 PM, Alice Mikityanska wrote: >> From: Alice Mikityanska <alice@isovalent.com> >> >> 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 can generate such >> a malformed packet. >> >> Blocking malformed virtio_net packets is implemented in the next 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. > > Minor nit: I think it would make sense to re-order the patches. > >> Signed-off-by: Alice Mikityanska <alice@isovalent.com> >> --- >> net/core/skbuff.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/net/core/skbuff.c b/net/core/skbuff.c >> index c82a1472a5ea..439cbfeb02bd 100644 >> --- a/net/core/skbuff.c >> +++ b/net/core/skbuff.c >> @@ -4860,7 +4860,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, >> * doesn't fit into an MSS sized block, so take care of that >> * now. >> */ >> - partial_segs = len / mss; >> + partial_segs = min(len / mss, GSO_MAX_SEGS); > > Since on top of patch 2/2 the min() should always be a no-op, Not sure; it'll be a no-op in this specific virtio_net scenario, but what if there are more? > what about instead: > > if (WARN_ON_ONCE(len/mss > GSO_MAX_SEGS)) > return ERR_PTR(-EINVAL); Yeah, it looks like a good idea to add a WARN to let syzbot uncover more possible cases, but: 1. I'd keep it non-failing rather than return an error: partial GSO can deal with smaller segment size pretty well, no need to fail. 2. I'd make it DEBUG_NET_WARN_ON_ONCE to avoid the penalty in production. I can do that if it passes Eric's filter for too much code in fastpath. > ? > > /P ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net-next v2 2/2] virtio-net: Ensure that TCP packets don't overflow gso_segs 2026-08-13 17:46 [PATCH net-next v2 0/2] Guard against gso_segs overflows Alice Mikityanska 2026-08-13 17:46 ` [PATCH net-next v2 1/2] net: Guard for gso_segs overflow in skb_segment Alice Mikityanska @ 2026-08-13 17:46 ` Alice Mikityanska 1 sibling, 0 replies; 5+ messages in thread From: Alice Mikityanska @ 2026-08-13 17:46 UTC (permalink / raw) To: Paolo Abeni, Jakub Kicinski, Eric Dumazet, Michael S. Tsirkin, Jason Wang Cc: David S. Miller, Simon Horman, Xuan Zhuo, Eugenio Pérez, Jason Xing, Kuniyuki Iwashima, Björn Töpel, Jiayuan Chen, netdev, Alice Mikityanska From: Alice Mikityanska <alice@isovalent.com> The user can specify any gso_size in a packet crafted with an AF_PACKET PACKET_VNET_HDR socket, even smaller than TCP_MIN_GSO_SIZE = 8. At the same time, GSO_MAX_SIZE = 8 * GSO_MAX_SEGS = 8 * 65535. When the user crafts a packet with gso_size < 8, there is a risk for partial GSO to overflow the 16-bit gso_segs field when dividing the SKB length by gso_size. Adjust gso_size of TCP packets to be at least TCP_MIN_GSO_SIZE = 8. Keep gso_size of UDP GSO packets, as gso_size=1 is valid and explicitly tested at tools/testing/selftests/net/tun.c:649. Signed-off-by: Alice Mikityanska <alice@isovalent.com> Suggested-by: Eric Dumazet <edumazet@google.com> --- include/linux/virtio_net.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index f36d21b5bc19..c381b916c1b5 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -6,6 +6,7 @@ #include <linux/ip.h> #include <linux/ipv6.h> #include <linux/udp.h> +#include <net/tcp.h> #include <uapi/linux/tcp.h> #include <uapi/linux/virtio_net.h> @@ -179,6 +180,9 @@ static inline int __virtio_net_hdr_to_skb(struct sk_buff *skb, if (skb->ip_summed == CHECKSUM_PARTIAL && skb->csum_offset != offsetof(struct tcphdr, check)) return -EINVAL; + + BUILD_BUG_ON(TCP_MIN_GSO_SIZE * GSO_MAX_SEGS < GSO_MAX_SIZE); + gso_size = max(gso_size, TCP_MIN_GSO_SIZE); break; } -- 2.55.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-19 17:21 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-13 17:46 [PATCH net-next v2 0/2] Guard against gso_segs overflows Alice Mikityanska 2026-08-13 17:46 ` [PATCH net-next v2 1/2] net: Guard for gso_segs overflow in skb_segment Alice Mikityanska 2026-08-18 13:38 ` Paolo Abeni 2026-08-19 17:18 ` Alice Mikityanska 2026-08-13 17:46 ` [PATCH net-next v2 2/2] virtio-net: Ensure that TCP packets don't overflow gso_segs Alice Mikityanska
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox