1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Sat, 27 Apr 2024 19:29:45 +0200
3 Subject: [PATCH] net: core: reject skb_copy(_expand) for fraglist GSO skbs
5 SKB_GSO_FRAGLIST skbs must not be linearized, otherwise they become
6 invalid. Return NULL if such an skb is passed to skb_copy or
7 skb_copy_expand, in order to prevent a crash on a potential later
8 call to skb_gso_segment.
10 Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.")
11 Signed-off-by: Felix Fietkau <nbd@nbd.name>
14 --- a/net/core/skbuff.c
15 +++ b/net/core/skbuff.c
16 @@ -1720,11 +1720,17 @@ static inline int skb_alloc_rx_flag(cons
18 struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
20 - int headerlen = skb_headroom(skb);
21 - unsigned int size = skb_end_offset(skb) + skb->data_len;
22 - struct sk_buff *n = __alloc_skb(size, gfp_mask,
23 - skb_alloc_rx_flag(skb), NUMA_NO_NODE);
28 + if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST))
31 + headerlen = skb_headroom(skb);
32 + size = skb_end_offset(skb) + skb->data_len;
33 + n = __alloc_skb(size, gfp_mask,
34 + skb_alloc_rx_flag(skb), NUMA_NO_NODE);
38 @@ -2037,12 +2043,17 @@ struct sk_buff *skb_copy_expand(const st
40 * Allocate the copy buffer
42 - struct sk_buff *n = __alloc_skb(newheadroom + skb->len + newtailroom,
43 - gfp_mask, skb_alloc_rx_flag(skb),
45 - int oldheadroom = skb_headroom(skb);
46 int head_copy_len, head_copy_off;
50 + if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST))
53 + oldheadroom = skb_headroom(skb);
54 + n = __alloc_skb(newheadroom + skb->len + newtailroom,
55 + gfp_mask, skb_alloc_rx_flag(skb),