Skip to content

Commit 5e6bf35

Browse files
committed
Merge: CVE-2024-43817: net: missing check virtio
MR: https://gitlab.com/redhat/rhel/src/kernel/rhel-9/-/merge_requests/2365 CVE: CVE-2024-43817 backport e269d79 ("net: missing check virtio") to fix the CVE 89add40 ("net: drop bad gso csum_start and offset in virtio_net_hdr") is a fix for e269d79 backport fc8b2a6 ("net: more strict VIRTIO_NET_HDR_GSO_UDP_L4 validation") to have the correct context for 89add40 (a case() with SKB_GSO_UDP and SKB_GSO_UDP_L4 rather than a if()" 1382e3b ("net: change maximum number of UDP segments to 128") is a fix for fc8b2a6 Omitted-fix: b128ed5 ("udp: fix receiving fraglist GSO packets") We don't need b128ed5 ("udp: fix receiving fraglist GSO packets") that is a fix for 89add40 because it adds only "!(skb_shinfo(gso_skb)-\>gso_type & SKB_GSO_FRAGLIST)" on the line that cannot happens because 9840036 ("gso: fix dodgy bit handling for GSO_UDP_L4") is not backported. JIRA: https://issues.redhat.com/browse/RHEL-54891 Signed-off-by: Laurent Vivier <lvivier@redhat.com> Approved-by: Jason Wang <jasowang@redhat.com> Approved-by: Florian Westphal <fwestpha@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Lucas Zampieri <lzampier@redhat.com>
2 parents 6337ce5 + 81744de commit 5e6bf35

File tree

5 files changed

+30
-5
lines changed

5 files changed

+30
-5
lines changed

include/linux/udp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ struct udp_sock {
9191
int forward_threshold;
9292
};
9393

94-
#define UDP_MAX_SEGMENTS (1 << 6UL)
94+
#define UDP_MAX_SEGMENTS (1 << 7UL)
9595

9696
static inline struct udp_sock *udp_sk(const struct sock *sk)
9797
{

include/linux/virtio_net.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#define _LINUX_VIRTIO_NET_H
44

55
#include <linux/if_vlan.h>
6+
#include <linux/udp.h>
67
#include <uapi/linux/tcp.h>
7-
#include <uapi/linux/udp.h>
88
#include <uapi/linux/virtio_net.h>
99

1010
static inline bool virtio_net_hdr_match_proto(__be16 protocol, __u8 gso_type)
@@ -151,9 +151,27 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
151151
unsigned int nh_off = p_off;
152152
struct skb_shared_info *shinfo = skb_shinfo(skb);
153153

154-
/* UFO may not include transport header in gso_size. */
155-
if (gso_type & SKB_GSO_UDP)
154+
switch (gso_type & ~SKB_GSO_TCP_ECN) {
155+
case SKB_GSO_UDP:
156+
/* UFO may not include transport header in gso_size. */
156157
nh_off -= thlen;
158+
break;
159+
case SKB_GSO_UDP_L4:
160+
if (!(hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM))
161+
return -EINVAL;
162+
if (skb->csum_offset != offsetof(struct udphdr, check))
163+
return -EINVAL;
164+
if (skb->len - p_off > gso_size * UDP_MAX_SEGMENTS)
165+
return -EINVAL;
166+
if (gso_type != SKB_GSO_UDP_L4)
167+
return -EINVAL;
168+
break;
169+
case SKB_GSO_TCPV4:
170+
case SKB_GSO_TCPV6:
171+
if (skb->csum_offset != offsetof(struct tcphdr, check))
172+
return -EINVAL;
173+
break;
174+
}
157175

158176
/* Too small packets are not really GSO ones. */
159177
if (skb->len - nh_off > gso_size) {

net/ipv4/tcp_offload.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
7373
if (thlen < sizeof(*th))
7474
goto out;
7575

76+
if (unlikely(skb_checksum_start(skb) != skb_transport_header(skb)))
77+
goto out;
78+
7679
if (!pskb_may_pull(skb, thlen))
7780
goto out;
7881

net/ipv4/udp_offload.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
281281
if (gso_skb->len <= sizeof(*uh) + mss)
282282
return ERR_PTR(-EINVAL);
283283

284+
if (unlikely(skb_checksum_start(gso_skb) !=
285+
skb_transport_header(gso_skb)))
286+
return ERR_PTR(-EINVAL);
287+
284288
skb_pull(gso_skb, sizeof(*uh));
285289

286290
/* clear destructor to avoid skb_segment assigning it to tail */

tools/testing/selftests/net/udpgso.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#endif
3535

3636
#ifndef UDP_MAX_SEGMENTS
37-
#define UDP_MAX_SEGMENTS (1 << 6UL)
37+
#define UDP_MAX_SEGMENTS (1 << 7UL)
3838
#endif
3939

4040
#define CONST_MTU_TEST 1500

0 commit comments

Comments
 (0)