Skip to content

Commit 04a8995

Browse files
borkmannMartin KaFai Lau
authored andcommitted
bpf: Do not let BPF test infra emit invalid GSO types to stack
Yinhao et al. reported that their fuzzer tool was able to trigger a skb_warn_bad_offload() from netif_skb_features() -> gso_features_check(). When a BPF program - triggered via BPF test infra - pushes the packet to the loopback device via bpf_clone_redirect() then mentioned offload warning can be seen. GSO-related features are then rightfully disabled. We get into this situation due to convert___skb_to_skb() setting gso_segs and gso_size but not gso_type. Technically, it makes sense that this warning triggers since the GSO properties are malformed due to the gso_type. Potentially, the gso_type could be marked non-trustworthy through setting it at least to SKB_GSO_DODGY without any other specific assumptions, but that also feels wrong given we should not go further into the GSO engine in the first place. The checks were added in 121d57a ("gso: validate gso_type in GSO handlers") because there were malicious (syzbot) senders that combine a protocol with a non-matching gso_type. If we would want to drop such packets, gso_features_check() currently only returns feature flags via netif_skb_features(), so one location for potentially dropping such skbs could be validate_xmit_unreadable_skb(), but then otoh it would be an additional check in the fast-path for a very corner case. Given bpf_clone_redirect() is the only place where BPF test infra could emit such packets, lets reject them right there. Fixes: 850a88c ("bpf: Expose __sk_buff wire_len/gso_segs to BPF_PROG_TEST_RUN") Fixes: cf62089 ("bpf: Add gso_size to __sk_buff") Reported-by: Yinhao Hu <[email protected]> Reported-by: Kaiyan Mei <[email protected]> Reported-by: Dongliang Mu <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: Martin KaFai Lau <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent 7361c86 commit 04a8995

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

net/bpf/test_run.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,11 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb)
945945

946946
if (__skb->gso_segs > GSO_MAX_SEGS)
947947
return -EINVAL;
948+
949+
/* Currently GSO type is zero/unset. If this gets extended with
950+
* a small list of accepted GSO types in future, the filter for
951+
* an unset GSO type in bpf_clone_redirect() can be lifted.
952+
*/
948953
skb_shinfo(skb)->gso_segs = __skb->gso_segs;
949954
skb_shinfo(skb)->gso_size = __skb->gso_size;
950955
skb_shinfo(skb)->hwtstamps.hwtstamp = __skb->hwtstamp;

net/core/filter.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,6 +2458,13 @@ BPF_CALL_3(bpf_clone_redirect, struct sk_buff *, skb, u32, ifindex, u64, flags)
24582458
if (unlikely(flags & (~(BPF_F_INGRESS) | BPF_F_REDIRECT_INTERNAL)))
24592459
return -EINVAL;
24602460

2461+
/* BPF test infra's convert___skb_to_skb() can create type-less
2462+
* GSO packets. gso_features_check() will detect this as a bad
2463+
* offload. However, lets not leak them out in the first place.
2464+
*/
2465+
if (unlikely(skb_is_gso(skb) && !skb_shinfo(skb)->gso_type))
2466+
return -EBADMSG;
2467+
24612468
dev = dev_get_by_index_rcu(dev_net(skb->dev), ifindex);
24622469
if (unlikely(!dev))
24632470
return -EINVAL;

0 commit comments

Comments
 (0)