--- /dev/null
+From willemdebruijn.kernel@gmail.com Mon Sep 9 20:25:15 2024
+From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Date: Mon, 9 Sep 2024 14:22:47 -0400
+Subject: gso: fix dodgy bit handling for GSO_UDP_L4
+To: stable@vger.kernel.org
+Cc: netdev@vger.kernel.org, gregkh@linuxfoundation.org, christian@theune.cc, mathieu.tortuyaux@gmail.com, Yan Zhai <yan@cloudflare.com>, Willem de Bruijn <willemdebruijn.kernel@gmail.com>, Willem de Bruijn <willemb@google.com>, Jason Wang <jasowang@redhat.com>, "David S. Miller" <davem@davemloft.net>
+Message-ID: <20240909182506.270136-4-willemdebruijn.kernel@gmail.com>
+
+From: Yan Zhai <yan@cloudflare.com>
+
+[ Upstream commit 9840036786d90cea11a90d1f30b6dc003b34ee67 ]
+
+Commit 1fd54773c267 ("udp: allow header check for dodgy GSO_UDP_L4
+packets.") checks DODGY bit for UDP, but for packets that can be fed
+directly to the device after gso_segs reset, it actually falls through
+to fragmentation:
+
+https://lore.kernel.org/all/CAJPywTKDdjtwkLVUW6LRA2FU912qcDmQOQGt2WaDo28KzYDg+A@mail.gmail.com/
+
+This change restores the expected behavior of GSO_UDP_L4 packets.
+
+Fixes: 1fd54773c267 ("udp: allow header check for dodgy GSO_UDP_L4 packets.")
+Suggested-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Signed-off-by: Yan Zhai <yan@cloudflare.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+
+[5.15 stable: clean backport]
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/udp_offload.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -272,13 +272,20 @@ struct sk_buff *__udp_gso_segment(struct
+ __sum16 check;
+ __be16 newlen;
+
+- if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST)
+- return __udp_gso_segment_list(gso_skb, features, is_ipv6);
+-
+ mss = skb_shinfo(gso_skb)->gso_size;
+ if (gso_skb->len <= sizeof(*uh) + mss)
+ return ERR_PTR(-EINVAL);
+
++ if (skb_gso_ok(gso_skb, features | NETIF_F_GSO_ROBUST)) {
++ /* Packet is from an untrusted source, reset gso_segs. */
++ skb_shinfo(gso_skb)->gso_segs = DIV_ROUND_UP(gso_skb->len - sizeof(*uh),
++ mss);
++ return NULL;
++ }
++
++ if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST)
++ return __udp_gso_segment_list(gso_skb, features, is_ipv6);
++
+ skb_pull(gso_skb, sizeof(*uh));
+
+ /* clear destructor to avoid skb_segment assigning it to tail */
--- /dev/null
+From stable+bounces-74079-greg=kroah.com@vger.kernel.org Mon Sep 9 20:25:31 2024
+From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Date: Mon, 9 Sep 2024 14:22:46 -0400
+Subject: net: change maximum number of UDP segments to 128
+To: stable@vger.kernel.org
+Cc: netdev@vger.kernel.org, gregkh@linuxfoundation.org, christian@theune.cc, mathieu.tortuyaux@gmail.com, Yuri Benditovich <yuri.benditovich@daynix.com>, Willem de Bruijn <willemb@google.com>, "David S. Miller" <davem@davemloft.net>
+Message-ID: <20240909182506.270136-3-willemdebruijn.kernel@gmail.com>
+
+From: Yuri Benditovich <yuri.benditovich@daynix.com>
+
+[ Upstream commit 1382e3b6a3500c245e5278c66d210c02926f804f ]
+
+The commit fc8b2a619469
+("net: more strict VIRTIO_NET_HDR_GSO_UDP_L4 validation")
+adds check of potential number of UDP segments vs
+UDP_MAX_SEGMENTS in linux/virtio_net.h.
+After this change certification test of USO guest-to-guest
+transmit on Windows driver for virtio-net device fails,
+for example with packet size of ~64K and mss of 536 bytes.
+In general the USO should not be more restrictive than TSO.
+Indeed, in case of unreasonably small mss a lot of segments
+can cause queue overflow and packet loss on the destination.
+Limit of 128 segments is good for any practical purpose,
+with minimal meaningful mss of 536 the maximal UDP packet will
+be divided to ~120 segments.
+The number of segments for UDP packets is validated vs
+UDP_MAX_SEGMENTS also in udp.c (v4,v6), this does not affect
+quest-to-guest path but does affect packets sent to host, for
+example.
+It is important to mention that UDP_MAX_SEGMENTS is kernel-only
+define and not available to user mode socket applications.
+In order to request MSS smaller than MTU the applications
+just uses setsockopt with SOL_UDP and UDP_SEGMENT and there is
+no limitations on socket API level.
+
+Fixes: fc8b2a619469 ("net: more strict VIRTIO_NET_HDR_GSO_UDP_L4 validation")
+Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+
+[5.15-stable: fix conflict with neighboring but unrelated code from
+ e2a4392b61f6 ("udp: introduce udp->udp_flags")
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/udp.h | 2 +-
+ tools/testing/selftests/net/udpgso.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/include/linux/udp.h
++++ b/include/linux/udp.h
+@@ -94,7 +94,7 @@ struct udp_sock {
+ int forward_deficit;
+ };
+
+-#define UDP_MAX_SEGMENTS (1 << 6UL)
++#define UDP_MAX_SEGMENTS (1 << 7UL)
+
+ static inline struct udp_sock *udp_sk(const struct sock *sk)
+ {
+--- a/tools/testing/selftests/net/udpgso.c
++++ b/tools/testing/selftests/net/udpgso.c
+@@ -34,7 +34,7 @@
+ #endif
+
+ #ifndef UDP_MAX_SEGMENTS
+-#define UDP_MAX_SEGMENTS (1 << 6UL)
++#define UDP_MAX_SEGMENTS (1 << 7UL)
+ #endif
+
+ #define CONST_MTU_TEST 1500
--- /dev/null
+From willemdebruijn.kernel@gmail.com Mon Sep 9 20:25:16 2024
+From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Date: Mon, 9 Sep 2024 14:22:48 -0400
+Subject: net: drop bad gso csum_start and offset in virtio_net_hdr
+To: stable@vger.kernel.org
+Cc: netdev@vger.kernel.org, gregkh@linuxfoundation.org, christian@theune.cc, mathieu.tortuyaux@gmail.com, Willem de Bruijn <willemb@google.com>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20240909182506.270136-5-willemdebruijn.kernel@gmail.com>
+
+From: Willem de Bruijn <willemb@google.com>
+
+[ Upstream commit 89add40066f9ed9abe5f7f886fe5789ff7e0c50e ]
+
+Tighten csum_start and csum_offset checks in virtio_net_hdr_to_skb
+for GSO packets.
+
+The function already checks that a checksum requested with
+VIRTIO_NET_HDR_F_NEEDS_CSUM is in skb linear. But for GSO packets
+this might not hold for segs after segmentation.
+
+Syzkaller demonstrated to reach this warning in skb_checksum_help
+
+ offset = skb_checksum_start_offset(skb);
+ ret = -EINVAL;
+ if (WARN_ON_ONCE(offset >= skb_headlen(skb)))
+
+By injecting a TSO packet:
+
+WARNING: CPU: 1 PID: 3539 at net/core/dev.c:3284 skb_checksum_help+0x3d0/0x5b0
+ ip_do_fragment+0x209/0x1b20 net/ipv4/ip_output.c:774
+ ip_finish_output_gso net/ipv4/ip_output.c:279 [inline]
+ __ip_finish_output+0x2bd/0x4b0 net/ipv4/ip_output.c:301
+ iptunnel_xmit+0x50c/0x930 net/ipv4/ip_tunnel_core.c:82
+ ip_tunnel_xmit+0x2296/0x2c70 net/ipv4/ip_tunnel.c:813
+ __gre_xmit net/ipv4/ip_gre.c:469 [inline]
+ ipgre_xmit+0x759/0xa60 net/ipv4/ip_gre.c:661
+ __netdev_start_xmit include/linux/netdevice.h:4850 [inline]
+ netdev_start_xmit include/linux/netdevice.h:4864 [inline]
+ xmit_one net/core/dev.c:3595 [inline]
+ dev_hard_start_xmit+0x261/0x8c0 net/core/dev.c:3611
+ __dev_queue_xmit+0x1b97/0x3c90 net/core/dev.c:4261
+ packet_snd net/packet/af_packet.c:3073 [inline]
+
+The geometry of the bad input packet at tcp_gso_segment:
+
+[ 52.003050][ T8403] skb len=12202 headroom=244 headlen=12093 tailroom=0
+[ 52.003050][ T8403] mac=(168,24) mac_len=24 net=(192,52) trans=244
+[ 52.003050][ T8403] shinfo(txflags=0 nr_frags=1 gso(size=1552 type=3 segs=0))
+[ 52.003050][ T8403] csum(0x60000c7 start=199 offset=1536
+ip_summed=3 complete_sw=0 valid=0 level=0)
+
+Mitigate with stricter input validation.
+
+csum_offset: for GSO packets, deduce the correct value from gso_type.
+This is already done for USO. Extend it to TSO. Let UFO be:
+udp[46]_ufo_fragment ignores these fields and always computes the
+checksum in software.
+
+csum_start: finding the real offset requires parsing to the transport
+header. Do not add a parser, use existing segmentation parsing. Thanks
+to SKB_GSO_DODGY, that also catches bad packets that are hw offloaded.
+Again test both TSO and USO. Do not test UFO for the above reason, and
+do not test UDP tunnel offload.
+
+GSO packet are almost always CHECKSUM_PARTIAL. USO packets may be
+CHECKSUM_NONE since commit 10154dbded6d6 ("udp: Allow GSO transmit
+from devices with no checksum offload"), but then still these fields
+are initialized correctly in udp4_hwcsum/udp6_hwcsum_outgoing. So no
+need to test for ip_summed == CHECKSUM_PARTIAL first.
+
+This revises an existing fix mentioned in the Fixes tag, which broke
+small packets with GSO offload, as detected by kselftests.
+
+Link: https://syzkaller.appspot.com/bug?extid=e1db31216c789f552871
+Link: https://lore.kernel.org/netdev/20240723223109.2196886-1-kuba@kernel.org
+Fixes: e269d79c7d35 ("net: missing check virtio")
+Cc: stable@vger.kernel.org
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20240729201108.1615114-1-willemdebruijn.kernel@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+
+[5.15 stable: clean backport]
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/virtio_net.h | 16 +++++-----------
+ net/ipv4/tcp_offload.c | 3 +++
+ net/ipv4/udp_offload.c | 4 ++++
+ 3 files changed, 12 insertions(+), 11 deletions(-)
+
+--- a/include/linux/virtio_net.h
++++ b/include/linux/virtio_net.h
+@@ -51,7 +51,6 @@ static inline int virtio_net_hdr_to_skb(
+ unsigned int thlen = 0;
+ unsigned int p_off = 0;
+ unsigned int ip_proto;
+- u64 ret, remainder, gso_size;
+
+ if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+ switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+@@ -88,16 +87,6 @@ static inline int virtio_net_hdr_to_skb(
+ u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
+ u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16));
+
+- if (hdr->gso_size) {
+- gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size);
+- ret = div64_u64_rem(skb->len, gso_size, &remainder);
+- if (!(ret && (hdr->gso_size > needed) &&
+- ((remainder > needed) || (remainder == 0)))) {
+- return -EINVAL;
+- }
+- skb_shinfo(skb)->tx_flags |= SKBFL_SHARED_FRAG;
+- }
+-
+ if (!pskb_may_pull(skb, needed))
+ return -EINVAL;
+
+@@ -170,6 +159,11 @@ retry:
+ if (gso_type != SKB_GSO_UDP_L4)
+ return -EINVAL;
+ break;
++ case SKB_GSO_TCPV4:
++ case SKB_GSO_TCPV6:
++ if (skb->csum_offset != offsetof(struct tcphdr, check))
++ return -EINVAL;
++ break;
+ }
+
+ /* Kernel has a special handling for GSO_BY_FRAGS. */
+--- a/net/ipv4/tcp_offload.c
++++ b/net/ipv4/tcp_offload.c
+@@ -71,6 +71,9 @@ struct sk_buff *tcp_gso_segment(struct s
+ if (thlen < sizeof(*th))
+ goto out;
+
++ if (unlikely(skb_checksum_start(skb) != skb_transport_header(skb)))
++ goto out;
++
+ if (!pskb_may_pull(skb, thlen))
+ goto out;
+
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -276,6 +276,10 @@ struct sk_buff *__udp_gso_segment(struct
+ if (gso_skb->len <= sizeof(*uh) + mss)
+ return ERR_PTR(-EINVAL);
+
++ if (unlikely(skb_checksum_start(gso_skb) !=
++ skb_transport_header(gso_skb)))
++ return ERR_PTR(-EINVAL);
++
+ if (skb_gso_ok(gso_skb, features | NETIF_F_GSO_ROBUST)) {
+ /* Packet is from an untrusted source, reset gso_segs. */
+ skb_shinfo(gso_skb)->gso_segs = DIV_ROUND_UP(gso_skb->len - sizeof(*uh),
--- /dev/null
+From stable+bounces-74078-greg=kroah.com@vger.kernel.org Mon Sep 9 20:25:27 2024
+From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Date: Mon, 9 Sep 2024 14:22:45 -0400
+Subject: net: more strict VIRTIO_NET_HDR_GSO_UDP_L4 validation
+To: stable@vger.kernel.org
+Cc: netdev@vger.kernel.org, gregkh@linuxfoundation.org, christian@theune.cc, mathieu.tortuyaux@gmail.com, Willem de Bruijn <willemb@google.com>, syzbot+01cdbc31e9c0ae9b33ac@syzkaller.appspotmail.com, syzbot+c99d835ff081ca30f986@syzkaller.appspotmail.com, Eric Dumazet <edumazet@google.com>, Jason Wang <jasowang@redhat.com>, "David S. Miller" <davem@davemloft.net>
+Message-ID: <20240909182506.270136-2-willemdebruijn.kernel@gmail.com>
+
+From: Willem de Bruijn <willemb@google.com>
+
+[ Upstream commit fc8b2a619469378717e7270d2a4e1ef93c585f7a ]
+
+Syzbot reported two new paths to hit an internal WARNING using the
+new virtio gso type VIRTIO_NET_HDR_GSO_UDP_L4.
+
+ RIP: 0010:skb_checksum_help+0x4a2/0x600 net/core/dev.c:3260
+ skb len=64521 gso_size=344
+and
+
+ RIP: 0010:skb_warn_bad_offload+0x118/0x240 net/core/dev.c:3262
+
+Older virtio types have historically had loose restrictions, leading
+to many entirely impractical fuzzer generated packets causing
+problems deep in the kernel stack. Ideally, we would have had strict
+validation for all types from the start.
+
+New virtio types can have tighter validation. Limit UDP GSO packets
+inserted via virtio to the same limits imposed by the UDP_SEGMENT
+socket interface:
+
+1. must use checksum offload
+2. checksum offload matches UDP header
+3. no more segments than UDP_MAX_SEGMENTS
+4. UDP GSO does not take modifier flags, notably SKB_GSO_TCP_ECN
+
+Fixes: 860b7f27b8f7 ("linux/virtio_net.h: Support USO offload in vnet header.")
+Reported-by: syzbot+01cdbc31e9c0ae9b33ac@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/0000000000005039270605eb0b7f@google.com/
+Reported-by: syzbot+c99d835ff081ca30f986@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/0000000000005426680605eb0b9f@google.com/
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+
+[5.15 stable: clean backport]
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/virtio_net.h | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+--- a/include/linux/virtio_net.h
++++ b/include/linux/virtio_net.h
+@@ -3,8 +3,8 @@
+ #define _LINUX_VIRTIO_NET_H
+
+ #include <linux/if_vlan.h>
++#include <linux/udp.h>
+ #include <uapi/linux/tcp.h>
+-#include <uapi/linux/udp.h>
+ #include <uapi/linux/virtio_net.h>
+
+ static inline bool virtio_net_hdr_match_proto(__be16 protocol, __u8 gso_type)
+@@ -155,9 +155,22 @@ retry:
+ unsigned int nh_off = p_off;
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
+
+- /* UFO may not include transport header in gso_size. */
+- if (gso_type & SKB_GSO_UDP)
++ switch (gso_type & ~SKB_GSO_TCP_ECN) {
++ case SKB_GSO_UDP:
++ /* UFO may not include transport header in gso_size. */
+ nh_off -= thlen;
++ break;
++ case SKB_GSO_UDP_L4:
++ if (!(hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM))
++ return -EINVAL;
++ if (skb->csum_offset != offsetof(struct udphdr, check))
++ return -EINVAL;
++ if (skb->len - p_off > gso_size * UDP_MAX_SEGMENTS)
++ return -EINVAL;
++ if (gso_type != SKB_GSO_UDP_L4)
++ return -EINVAL;
++ break;
++ }
+
+ /* Kernel has a special handling for GSO_BY_FRAGS. */
+ if (gso_size == GSO_BY_FRAGS)
drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch
drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch
gpio-rockchip-fix-of-node-leak-in-probe.patch
+net-more-strict-virtio_net_hdr_gso_udp_l4-validation.patch
+net-change-maximum-number-of-udp-segments-to-128.patch
+gso-fix-dodgy-bit-handling-for-gso_udp_l4.patch
+net-drop-bad-gso-csum_start-and-offset-in-virtio_net_hdr.patch