diff --git a/net/core/filter.c b/net/core/filter.c index 303c0c44dc2c..c0fc9ff04bd5 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3762,6 +3762,14 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff, return -ENOTSUPP; } + /* + * The MSS is raised by len_diff. It has 16 bits, and GSO_BY_FRAGS is + * not a size. + */ + if (skb_is_gso(skb) && !(flags & BPF_F_ADJ_ROOM_FIXED_GSO) && + skb_shinfo(skb)->gso_size + len_diff >= GSO_BY_FRAGS) + return -ENOTSUPP; + ret = skb_unclone(skb, GFP_ATOMIC); if (unlikely(ret < 0)) return ret;