Link: https://nvd.nist.gov/vuln/detail/cve-2024-43817
[PATCH 5.10 1/5] net: more strict VIRTIO_NET_HDR_GSO_UDP_L4 validation [PATCH 5.10 2/5] net: drop bad gso csum_start and offset in virtio_net_hdr [PATCH 5.10 3/5] net: tighten bad gso csum offset check in virtio_net_hdr [PATCH 5.10 4/5] net: add more sanity check in virtio_net_hdr_to_skb() [PATCH 5.10 5/5] net: test for not too small csum_start in
The bug has been fixed "silently" in upstream with the following series of 5 commits.
49d14b54a527 net: test for not too small csum_start in virtio_net_hdr_to_skb() 6513eb3d3191 net: tighten bad gso csum offset check in virtio_net_hdr 89add40066f9 net: drop bad gso csum_start and offset in virtio_net_hdr 9181d6f8a2bb net: add more sanity check in virtio_net_hdr_to_skb() fc8b2a619469 net: more strict VIRTIO_NET_HDR_GSO_UDP_L4 validation
From: Willem de Bruijn willemb@google.com
commit fc8b2a619469378717e7270d2a4e1ef93c585f7a upstream.
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 [Denis: minor fix to resolve merge conflict.] Signed-off-by: Denis Arefev arefev@swemel.ru --- Backport fix for CVE-2024-43817 Link: https://nvd.nist.gov/vuln/detail/cve-2024-43817 --- include/linux/virtio_net.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 6047058d6703..9bdba0c00c07 100644 --- 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) @@ -144,9 +144,22 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, 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)
linux-stable-mirror@lists.linaro.org