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