~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/progs/exceptions_fail.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include <vmlinux.h>
  3 #include <bpf/bpf_tracing.h>
  4 #include <bpf/bpf_helpers.h>
  5 #include <bpf/bpf_core_read.h>
  6 
  7 #include "bpf_misc.h"
  8 #include "bpf_experimental.h"
  9 
 10 extern void bpf_rcu_read_lock(void) __ksym;
 11 
 12 #define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
 13 
 14 struct foo {
 15         struct bpf_rb_node node;
 16 };
 17 
 18 struct hmap_elem {
 19         struct bpf_timer timer;
 20 };
 21 
 22 struct {
 23         __uint(type, BPF_MAP_TYPE_HASH);
 24         __uint(max_entries, 64);
 25         __type(key, int);
 26         __type(value, struct hmap_elem);
 27 } hmap SEC(".maps");
 28 
 29 private(A) struct bpf_spin_lock lock;
 30 private(A) struct bpf_rb_root rbtree __contains(foo, node);
 31 
 32 __noinline void *exception_cb_bad_ret_type(u64 cookie)
 33 {
 34         return NULL;
 35 }
 36 
 37 __noinline int exception_cb_bad_arg_0(void)
 38 {
 39         return 0;
 40 }
 41 
 42 __noinline int exception_cb_bad_arg_2(int a, int b)
 43 {
 44         return 0;
 45 }
 46 
 47 __noinline int exception_cb_ok_arg_small(int a)
 48 {
 49         return 0;
 50 }
 51 
 52 SEC("?tc")
 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)
 56 {
 57         bpf_throw(0);
 58         return 0;
 59 }
 60 
 61 SEC("?tc")
 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)
 65 {
 66         bpf_throw(0);
 67         return 0;
 68 }
 69 
 70 SEC("?tc")
 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)
 74 {
 75         bpf_throw(0);
 76         return 0;
 77 }
 78 
 79 SEC("?tc")
 80 __exception_cb(exception_cb_ok_arg_small)
 81 __success
 82 int reject_exception_cb_type_4(struct __sk_buff *ctx)
 83 {
 84         bpf_throw(0);
 85         return 0;
 86 }
 87 
 88 __noinline
 89 static int timer_cb(void *map, int *key, struct bpf_timer *timer)
 90 {
 91         bpf_throw(0);
 92         return 0;
 93 }
 94 
 95 SEC("?tc")
 96 __failure __msg("cannot be called from callback subprog")
 97 int reject_async_callback_throw(struct __sk_buff *ctx)
 98 {
 99         struct hmap_elem *elem;
100 
101         elem = bpf_map_lookup_elem(&hmap, &(int){0});
102         if (!elem)
103                 return 0;
104         return bpf_timer_set_callback(&elem->timer, timer_cb);
105 }
106 
107 __noinline static int subprog_lock(struct __sk_buff *ctx)
108 {
109         volatile int ret = 0;
110 
111         bpf_spin_lock(&lock);
112         if (ctx->len)
113                 bpf_throw(0);
114         return ret;
115 }
116 
117 SEC("?tc")
118 __failure __msg("function calls are not allowed while holding a lock")
119 int reject_with_lock(void *ctx)
120 {
121         bpf_spin_lock(&lock);
122         bpf_throw(0);
123         return 0;
124 }
125 
126 SEC("?tc")
127 __failure __msg("function calls are not allowed while holding a lock")
128 int reject_subprog_with_lock(void *ctx)
129 {
130         return subprog_lock(ctx);
131 }
132 
133 SEC("?tc")
134 __failure __msg("bpf_rcu_read_unlock is missing")
135 int reject_with_rcu_read_lock(void *ctx)
136 {
137         bpf_rcu_read_lock();
138         bpf_throw(0);
139         return 0;
140 }
141 
142 __noinline static int throwing_subprog(struct __sk_buff *ctx)
143 {
144         if (ctx->len)
145                 bpf_throw(0);
146         return 0;
147 }
148 
149 SEC("?tc")
150 __failure __msg("bpf_rcu_read_unlock is missing")
151 int reject_subprog_with_rcu_read_lock(void *ctx)
152 {
153         bpf_rcu_read_lock();
154         return throwing_subprog(ctx);
155 }
156 
157 static bool rbless(struct bpf_rb_node *n1, const struct bpf_rb_node *n2)
158 {
159         bpf_throw(0);
160         return true;
161 }
162 
163 SEC("?tc")
164 __failure __msg("function calls are not allowed while holding a lock")
165 int reject_with_rbtree_add_throw(void *ctx)
166 {
167         struct foo *f;
168 
169         f = bpf_obj_new(typeof(*f));
170         if (!f)
171                 return 0;
172         bpf_spin_lock(&lock);
173         bpf_rbtree_add(&rbtree, &f->node, rbless);
174         bpf_spin_unlock(&lock);
175         return 0;
176 }
177 
178 SEC("?tc")
179 __failure __msg("Unreleased reference")
180 int reject_with_reference(void *ctx)
181 {
182         struct foo *f;
183 
184         f = bpf_obj_new(typeof(*f));
185         if (!f)
186                 return 0;
187         bpf_throw(0);
188         return 0;
189 }
190 
191 __noinline static int subprog_ref(struct __sk_buff *ctx)
192 {
193         struct foo *f;
194 
195         f = bpf_obj_new(typeof(*f));
196         if (!f)
197                 return 0;
198         bpf_throw(0);
199         return 0;
200 }
201 
202 __noinline static int subprog_cb_ref(u32 i, void *ctx)
203 {
204         bpf_throw(0);
205         return 0;
206 }
207 
208 SEC("?tc")
209 __failure __msg("Unreleased reference")
210 int reject_with_cb_reference(void *ctx)
211 {
212         struct foo *f;
213 
214         f = bpf_obj_new(typeof(*f));
215         if (!f)
216                 return 0;
217         bpf_loop(5, subprog_cb_ref, NULL, 0);
218         bpf_obj_drop(f);
219         return 0;
220 }
221 
222 SEC("?tc")
223 __failure __msg("cannot be called from callback")
224 int reject_with_cb(void *ctx)
225 {
226         bpf_loop(5, subprog_cb_ref, NULL, 0);
227         return 0;
228 }
229 
230 SEC("?tc")
231 __failure __msg("Unreleased reference")
232 int reject_with_subprog_reference(void *ctx)
233 {
234         return subprog_ref(ctx) + 1;
235 }
236 
237 __noinline int throwing_exception_cb(u64 c)
238 {
239         bpf_throw(0);
240         return c;
241 }
242 
243 __noinline int exception_cb1(u64 c)
244 {
245         return c;
246 }
247 
248 __noinline int exception_cb2(u64 c)
249 {
250         return c;
251 }
252 
253 static __noinline int static_func(struct __sk_buff *ctx)
254 {
255         return exception_cb1(ctx->tstamp);
256 }
257 
258 __noinline int global_func(struct __sk_buff *ctx)
259 {
260         return exception_cb1(ctx->tstamp);
261 }
262 
263 SEC("?tc")
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)
267 {
268         return 0;
269 }
270 
271 SEC("?tc")
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)
275 {
276         return global_func(ctx);
277 }
278 
279 SEC("?tc")
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)
283 {
284         return static_func(ctx);
285 }
286 
287 SEC("?tc")
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)
292 {
293         bpf_throw(0);
294         return 16;
295 }
296 
297 __noinline int exception_cb_bad_ret(u64 c)
298 {
299         return c;
300 }
301 
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)
306 {
307         return 0;
308 }
309 
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)
313 {
314         bpf_throw(64);
315         return 0;
316 }
317 
318 __noinline static int loop_cb1(u32 index, int *ctx)
319 {
320         bpf_throw(0);
321         return 0;
322 }
323 
324 __noinline static int loop_cb2(u32 index, int *ctx)
325 {
326         bpf_throw(0);
327         return 0;
328 }
329 
330 SEC("?tc")
331 __failure __msg("cannot be called from callback")
332 int reject_exception_throw_cb(struct __sk_buff *ctx)
333 {
334         bpf_loop(5, loop_cb1, NULL, 0);
335         return 0;
336 }
337 
338 SEC("?tc")
339 __failure __msg("cannot be called from callback")
340 int reject_exception_throw_cb_diff(struct __sk_buff *ctx)
341 {
342         if (ctx->protocol)
343                 bpf_loop(5, loop_cb1, NULL, 0);
344         else
345                 bpf_loop(5, loop_cb2, NULL, 0);
346         return 0;
347 }
348 
349 char _license[] SEC("license") = "GPL";
350 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php