xref: /linux/tools/testing/selftests/bpf/progs/bpf_qdisc_fail__invalid_dynptr_slice.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <vmlinux.h>
4 #include "bpf_experimental.h"
5 #include "bpf_qdisc_common.h"
6 #include "bpf_misc.h"
7 
8 char _license[] SEC("license") = "GPL";
9 
10 int proto;
11 
12 SEC("struct_ops")
13 __failure __msg("invalid mem access 'scalar'")
14 int BPF_PROG(invalid_dynptr_slice, struct sk_buff *skb, struct Qdisc *sch,
15 	     struct bpf_sk_buff_ptr *to_free)
16 {
17 	struct bpf_dynptr ptr;
18 	struct ethhdr *hdr;
19 
20 	bpf_dynptr_from_skb((struct __sk_buff *)skb, 0, &ptr);
21 
22 	hdr = bpf_dynptr_slice(&ptr, 0, NULL, sizeof(*hdr));
23 	if (!hdr) {
24 		bpf_qdisc_skb_drop(skb, to_free);
25 		return NET_XMIT_DROP;
26 	}
27 
28 	bpf_qdisc_skb_drop(skb, to_free);
29 
30 	proto = hdr->h_proto;
31 
32 	return NET_XMIT_DROP;
33 }
34 
35 SEC("struct_ops")
36 __auxiliary
37 struct sk_buff *BPF_PROG(bpf_qdisc_test_dequeue, struct Qdisc *sch)
38 {
39 	return NULL;
40 }
41 
42 SEC("struct_ops")
43 __auxiliary
44 int BPF_PROG(bpf_qdisc_test_init, struct Qdisc *sch, struct nlattr *opt,
45 	     struct netlink_ext_ack *extack)
46 {
47 	return 0;
48 }
49 
50 SEC("struct_ops")
51 __auxiliary
52 void BPF_PROG(bpf_qdisc_test_reset, struct Qdisc *sch)
53 {
54 }
55 
56 SEC("struct_ops")
57 __auxiliary
58 void BPF_PROG(bpf_qdisc_test_destroy, struct Qdisc *sch)
59 {
60 }
61 
62 SEC(".struct_ops")
63 struct Qdisc_ops test = {
64 	.enqueue   = (void *)invalid_dynptr_slice,
65 	.dequeue   = (void *)bpf_qdisc_test_dequeue,
66 	.init      = (void *)bpf_qdisc_test_init,
67 	.reset     = (void *)bpf_qdisc_test_reset,
68 	.destroy   = (void *)bpf_qdisc_test_destroy,
69 	.id        = "bpf_qdisc_test",
70 };
71