1 // SPDX-License-Identifier: GPL-2.0
3 #include <bpf/bpf_tracing.h>
4 #include <bpf/bpf_helpers.h>
5 #include <bpf/bpf_core_read.h>
8 #include "bpf_experimental.h"
10 extern void bpf_rcu_read_lock(void) __ksym;
12 #define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
15 struct bpf_rb_node node;
19 struct bpf_timer timer;
23 __uint(type, BPF_MAP_TYPE_HASH);
24 __uint(max_entries, 64);
26 __type(value, struct hmap_elem);
29 private(A) struct bpf_spin_lock lock;
30 private(A) struct bpf_rb_root rbtree __contains(foo, node);
32 __noinline void *exception_cb_bad_ret_type(u64 cookie)
37 __noinline int exception_cb_bad_arg_0(void)
42 __noinline int exception_cb_bad_arg_2(int a, int b)
47 __noinline int exception_cb_ok_arg_small(int a)
53 __exception_cb(exception_cb_bad_ret_type)
54 __failure __msg("Global function exception_cb_bad_ret_type() doesn't return scalar.")
55 int reject_exception_cb_type_1(struct __sk_buff *ctx)
62 __exception_cb(exception_cb_bad_arg_0)
63 __failure __msg("exception cb only supports single integer argument")
64 int reject_exception_cb_type_2(struct __sk_buff *ctx)
71 __exception_cb(exception_cb_bad_arg_2)
72 __failure __msg("exception cb only supports single integer argument")
73 int reject_exception_cb_type_3(struct __sk_buff *ctx)
80 __exception_cb(exception_cb_ok_arg_small)
82 int reject_exception_cb_type_4(struct __sk_buff *ctx)
89 static int timer_cb(void *map, int *key, struct bpf_timer *timer)
96 __failure __msg("cannot be called from callback subprog")
97 int reject_async_callback_throw(struct __sk_buff *ctx)
99 struct hmap_elem *elem;
101 elem = bpf_map_lookup_elem(&hmap, &(int){0});
104 return bpf_timer_set_callback(&elem->timer, timer_cb);
107 __noinline static int subprog_lock(struct __sk_buff *ctx)
109 volatile int ret = 0;
111 bpf_spin_lock(&lock);
118 __failure __msg("function calls are not allowed while holding a lock")
119 int reject_with_lock(void *ctx)
121 bpf_spin_lock(&lock);
127 __failure __msg("function calls are not allowed while holding a lock")
128 int reject_subprog_with_lock(void *ctx)
130 return subprog_lock(ctx);
134 __failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region")
135 int reject_with_rcu_read_lock(void *ctx)
142 __noinline static int throwing_subprog(struct __sk_buff *ctx)
150 __failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region")
151 int reject_subprog_with_rcu_read_lock(void *ctx)
154 return throwing_subprog(ctx);
157 static bool rbless(struct bpf_rb_node *n1, const struct bpf_rb_node *n2)
164 __failure __msg("function calls are not allowed while holding a lock")
165 int reject_with_rbtree_add_throw(void *ctx)
169 f = bpf_obj_new(typeof(*f));
172 bpf_spin_lock(&lock);
173 bpf_rbtree_add(&rbtree, &f->node, rbless);
174 bpf_spin_unlock(&lock);
179 __failure __msg("Unreleased reference")
180 int reject_with_reference(void *ctx)
184 f = bpf_obj_new(typeof(*f));
191 __noinline static int subprog_ref(struct __sk_buff *ctx)
195 f = bpf_obj_new(typeof(*f));
202 __noinline static int subprog_cb_ref(u32 i, void *ctx)
209 __failure __msg("Unreleased reference")
210 int reject_with_cb_reference(void *ctx)
214 f = bpf_obj_new(typeof(*f));
217 bpf_loop(5, subprog_cb_ref, NULL, 0);
223 __failure __msg("cannot be called from callback")
224 int reject_with_cb(void *ctx)
226 bpf_loop(5, subprog_cb_ref, NULL, 0);
231 __failure __msg("Unreleased reference")
232 int reject_with_subprog_reference(void *ctx)
234 return subprog_ref(ctx) + 1;
237 __noinline int throwing_exception_cb(u64 c)
243 __noinline int exception_cb1(u64 c)
248 __noinline int exception_cb2(u64 c)
253 static __noinline int static_func(struct __sk_buff *ctx)
255 return exception_cb1(ctx->tstamp);
258 __noinline int global_func(struct __sk_buff *ctx)
260 return exception_cb1(ctx->tstamp);
264 __exception_cb(throwing_exception_cb)
265 __failure __msg("cannot be called from callback subprog")
266 int reject_throwing_exception_cb(struct __sk_buff *ctx)
272 __exception_cb(exception_cb1)
273 __failure __msg("cannot call exception cb directly")
274 int reject_exception_cb_call_global_func(struct __sk_buff *ctx)
276 return global_func(ctx);
280 __exception_cb(exception_cb1)
281 __failure __msg("cannot call exception cb directly")
282 int reject_exception_cb_call_static_func(struct __sk_buff *ctx)
284 return static_func(ctx);
288 __exception_cb(exception_cb1)
289 __exception_cb(exception_cb2)
290 __failure __msg("multiple exception callback tags for main subprog")
291 int reject_multiple_exception_cb(struct __sk_buff *ctx)
297 __noinline int exception_cb_bad_ret(u64 c)
302 SEC("?fentry/bpf_check")
303 __exception_cb(exception_cb_bad_ret)
304 __failure __msg("At program exit the register R0 has unknown scalar value should")
305 int reject_set_exception_cb_bad_ret1(void *ctx)
310 SEC("?fentry/bpf_check")
311 __failure __msg("At program exit the register R1 has smin=64 smax=64 should")
312 int reject_set_exception_cb_bad_ret2(void *ctx)
318 __noinline static int loop_cb1(u32 index, int *ctx)
324 __noinline static int loop_cb2(u32 index, int *ctx)
331 __failure __msg("cannot be called from callback")
332 int reject_exception_throw_cb(struct __sk_buff *ctx)
334 bpf_loop(5, loop_cb1, NULL, 0);
339 __failure __msg("cannot be called from callback")
340 int reject_exception_throw_cb_diff(struct __sk_buff *ctx)
343 bpf_loop(5, loop_cb1, NULL, 0);
345 bpf_loop(5, loop_cb2, NULL, 0);
349 char _license[] SEC("license") = "GPL";