diff --git a/net/core/filter.c b/net/core/filter.c index 4a38c9b33bc9..00b7ebe4a02b 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3572,14 +3572,19 @@ static u32 bpf_skb_net_base_len(const struct sk_buff *skb) #define BPF_F_ADJ_ROOM_DECAP_L3_MASK (BPF_F_ADJ_ROOM_DECAP_L3_IPV4 | \ BPF_F_ADJ_ROOM_DECAP_L3_IPV6) -#define BPF_F_ADJ_ROOM_MASK (BPF_F_ADJ_ROOM_FIXED_GSO | \ - BPF_F_ADJ_ROOM_ENCAP_L3_MASK | \ +#define BPF_F_ADJ_ROOM_ENCAP_MASK (BPF_F_ADJ_ROOM_ENCAP_L3_MASK | \ BPF_F_ADJ_ROOM_ENCAP_L4_GRE | \ BPF_F_ADJ_ROOM_ENCAP_L4_UDP | \ BPF_F_ADJ_ROOM_ENCAP_L2_ETH | \ BPF_F_ADJ_ROOM_ENCAP_L2( \ - BPF_ADJ_ROOM_ENCAP_L2_MASK) | \ - BPF_F_ADJ_ROOM_DECAP_L3_MASK) + BPF_ADJ_ROOM_ENCAP_L2_MASK)) + +#define BPF_F_ADJ_ROOM_DECAP_MASK (BPF_F_ADJ_ROOM_DECAP_L3_MASK) + +#define BPF_F_ADJ_ROOM_MASK (BPF_F_ADJ_ROOM_FIXED_GSO | \ + BPF_F_ADJ_ROOM_ENCAP_MASK | \ + BPF_F_ADJ_ROOM_DECAP_MASK | \ + BPF_F_ADJ_ROOM_NO_CSUM_RESET) static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff, u64 flags) @@ -3702,8 +3707,8 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 off, u32 len_diff, bool decap = flags & BPF_F_ADJ_ROOM_DECAP_L3_MASK; int ret; - if (unlikely(flags & ~(BPF_F_ADJ_ROOM_FIXED_GSO | - BPF_F_ADJ_ROOM_DECAP_L3_MASK | + if (unlikely(flags & ~(BPF_F_ADJ_ROOM_DECAP_MASK | + BPF_F_ADJ_ROOM_FIXED_GSO | BPF_F_ADJ_ROOM_NO_CSUM_RESET))) return -EINVAL; @@ -3802,8 +3807,7 @@ BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff, u32 off; int ret; - if (unlikely(flags & ~(BPF_F_ADJ_ROOM_MASK | - BPF_F_ADJ_ROOM_NO_CSUM_RESET))) + if (unlikely(flags & ~BPF_F_ADJ_ROOM_MASK)) return -EINVAL; if (unlikely(len_diff_abs > 0xfffU)) return -EFAULT; @@ -3822,20 +3826,20 @@ BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff, return -ENOTSUPP; } - if (flags & BPF_F_ADJ_ROOM_DECAP_L3_MASK) { + if (flags & BPF_F_ADJ_ROOM_DECAP_MASK) { if (!shrink) return -EINVAL; - switch (flags & BPF_F_ADJ_ROOM_DECAP_L3_MASK) { - case BPF_F_ADJ_ROOM_DECAP_L3_IPV4: - len_min = sizeof(struct iphdr); - break; - case BPF_F_ADJ_ROOM_DECAP_L3_IPV6: - len_min = sizeof(struct ipv6hdr); - break; - default: + /* Reject mutually exclusive decap flag pairs. */ + if ((flags & BPF_F_ADJ_ROOM_DECAP_L3_MASK) == + BPF_F_ADJ_ROOM_DECAP_L3_MASK) return -EINVAL; - } + + if (flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV4) + len_min = sizeof(struct iphdr); + + if (flags & BPF_F_ADJ_ROOM_DECAP_L3_IPV6) + len_min = sizeof(struct ipv6hdr); } len_cur = skb->len - skb_network_offset(skb);