diff --git a/net/core/filter.c b/net/core/filter.c index f0eae1c14b2f..8167cbadc625 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3612,6 +3612,14 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, return -ENOTSUPP; } + /* + * The MSS is lowered by len_diff. Leave the least that the stack lets a + * TCP GSO packet have, or gso_segs can overflow. + */ + if (skb_is_gso(skb) && !(flags & BPF_F_ADJ_ROOM_FIXED_GSO) && + skb_shinfo(skb)->gso_size < len_diff + TCP_MIN_GSO_SIZE) + return -ENOTSUPP; + ret = skb_cow_head(skb, meta_len + len_diff); if (unlikely(ret < 0)) return ret;