1 // SPDX-License-Identifier: GPL-2.0 2 #include <bpf/btf.h> 3 #include <test_btf.h> 4 #include <linux/btf.h> 5 #include <test_progs.h> 6 #include <network_helpers.h> 7 8 #include "linked_list.skel.h" 9 #include "linked_list_fail.skel.h" 10 #include "linked_list_peek.skel.h" 11 12 static char log_buf[1024 * 1024]; 13 14 static struct { 15 const char *prog_name; 16 const char *err_msg; 17 } linked_list_fail_tests[] = { 18 #define TEST(test, off) \ 19 { #test "_missing_lock_push_front", \ 20 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \ 21 { #test "_missing_lock_push_back", \ 22 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \ 23 { #test "_missing_lock_pop_front", \ 24 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \ 25 { #test "_missing_lock_pop_back", \ 26 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, 27 TEST(kptr, 40) 28 TEST(global, 16) 29 TEST(map, 0) 30 TEST(inner_map, 0) 31 #undef TEST 32 #define TEST(test, op) \ 33 { #test "_kptr_incorrect_lock_" #op, \ 34 "held lock and object are not in the same allocation\n" \ 35 "bpf_spin_lock at off=40 must be held for bpf_list_head" }, \ 36 { #test "_global_incorrect_lock_" #op, \ 37 "held lock and object are not in the same allocation\n" \ 38 "bpf_spin_lock at off=16 must be held for bpf_list_head" }, \ 39 { #test "_map_incorrect_lock_" #op, \ 40 "held lock and object are not in the same allocation\n" \ 41 "bpf_spin_lock at off=0 must be held for bpf_list_head" }, \ 42 { #test "_inner_map_incorrect_lock_" #op, \ 43 "held lock and object are not in the same allocation\n" \ 44 "bpf_spin_lock at off=0 must be held for bpf_list_head" }, 45 TEST(kptr, push_front) 46 TEST(kptr, push_back) 47 TEST(kptr, pop_front) 48 TEST(kptr, pop_back) 49 TEST(global, push_front) 50 TEST(global, push_back) 51 TEST(global, pop_front) 52 TEST(global, pop_back) 53 TEST(map, push_front) 54 TEST(map, push_back) 55 TEST(map, pop_front) 56 TEST(map, pop_back) 57 TEST(inner_map, push_front) 58 TEST(inner_map, push_back) 59 TEST(inner_map, pop_front) 60 TEST(inner_map, pop_back) 61 #undef TEST 62 { "map_compat_kprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 63 { "map_compat_kretprobe", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 64 { "map_compat_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 65 { "map_compat_perf", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 66 { "map_compat_raw_tp", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 67 { "map_compat_raw_tp_w", "tracing progs cannot use bpf_{list_head,rb_root} yet" }, 68 { "obj_type_id_oor", "local type ID argument must be in range [0, U32_MAX]" }, 69 { "obj_new_no_composite", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" }, 70 { "obj_new_no_struct", "bpf_obj_new/bpf_percpu_obj_new type ID argument must be of a struct" }, 71 { "obj_drop_non_zero_off", "R1 must have zero offset when passed to release func" }, 72 { "new_null_ret", "R0 invalid mem access 'ptr_or_null_'" }, 73 { "obj_new_acq", "Unreleased reference id=" }, 74 { "use_after_drop", "invalid mem access 'scalar'" }, 75 { "ptr_walk_scalar", "type=rdonly_untrusted_mem expected=percpu_ptr_" }, 76 { "direct_read_lock", "direct access to bpf_spin_lock is disallowed" }, 77 { "direct_write_lock", "direct access to bpf_spin_lock is disallowed" }, 78 { "direct_read_head", "direct access to bpf_list_head is disallowed" }, 79 { "direct_write_head", "direct access to bpf_list_head is disallowed" }, 80 { "direct_read_node", "direct access to bpf_list_node is disallowed" }, 81 { "direct_write_node", "direct access to bpf_list_node is disallowed" }, 82 { "use_after_unlock_push_front", "invalid mem access 'scalar'" }, 83 { "use_after_unlock_push_back", "invalid mem access 'scalar'" }, 84 { "double_push_front", "R2 expected pointer to allocated object" }, 85 { "double_push_back", "R2 expected pointer to allocated object" }, 86 { "no_node_value_type", "bpf_list_node not found at offset=0" }, 87 { "incorrect_value_type", 88 "operation on bpf_list_head expects arg#1 bpf_list_node at offset=48 in struct foo, " 89 "but arg is at offset=0 in struct bar" }, 90 { "incorrect_node_var_off", "variable ptr_ access var_off=(0x0; 0x1ffffffff) disallowed" }, 91 { "incorrect_node_off1", "bpf_list_node not found at offset=49" }, 92 { "incorrect_node_off2", "arg#1 offset=0, but expected bpf_list_node at offset=48 in struct foo" }, 93 { "no_head_type", "bpf_list_head not found at offset=0" }, 94 { "incorrect_head_var_off1", "R1 doesn't have constant offset" }, 95 { "incorrect_head_var_off2", "variable ptr_ access var_off=(0x0; 0x1ffffffff) disallowed" }, 96 { "incorrect_head_off1", "bpf_list_head not found at offset=25" }, 97 { "incorrect_head_off2", "bpf_list_head not found at offset=1" }, 98 { "pop_front_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" }, 99 { "pop_back_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" }, 100 }; 101 102 static void test_linked_list_fail_prog(const char *prog_name, const char *err_msg) 103 { 104 LIBBPF_OPTS(bpf_object_open_opts, opts, .kernel_log_buf = log_buf, 105 .kernel_log_size = sizeof(log_buf), 106 .kernel_log_level = 1); 107 struct linked_list_fail *skel; 108 struct bpf_program *prog; 109 int ret; 110 111 skel = linked_list_fail__open_opts(&opts); 112 if (!ASSERT_OK_PTR(skel, "linked_list_fail__open_opts")) 113 return; 114 115 prog = bpf_object__find_program_by_name(skel->obj, prog_name); 116 if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) 117 goto end; 118 119 bpf_program__set_autoload(prog, true); 120 121 ret = linked_list_fail__load(skel); 122 if (!ASSERT_ERR(ret, "linked_list_fail__load must fail")) 123 goto end; 124 125 if (!ASSERT_OK_PTR(strstr(log_buf, err_msg), "expected error message")) { 126 fprintf(stderr, "Expected: %s\n", err_msg); 127 fprintf(stderr, "Verifier: %s\n", log_buf); 128 } 129 130 end: 131 linked_list_fail__destroy(skel); 132 } 133 134 static void clear_fields(struct bpf_program *prog) 135 { 136 LIBBPF_OPTS(bpf_test_run_opts, opts); 137 int ret; 138 139 ret = bpf_prog_test_run_opts(bpf_program__fd(prog), &opts); 140 ASSERT_OK(ret, "clear_fields"); 141 ASSERT_OK(opts.retval, "clear_fields retval"); 142 } 143 144 enum { 145 TEST_ALL, 146 PUSH_POP, 147 PUSH_POP_MULT, 148 LIST_IN_LIST, 149 }; 150 151 static void test_linked_list_success(int mode, bool leave_in_map) 152 { 153 LIBBPF_OPTS(bpf_test_run_opts, opts, 154 .data_in = &pkt_v4, 155 .data_size_in = sizeof(pkt_v4), 156 .repeat = 1, 157 ); 158 struct linked_list *skel; 159 int ret; 160 161 skel = linked_list__open_and_load(); 162 if (!ASSERT_OK_PTR(skel, "linked_list__open_and_load")) 163 return; 164 165 if (mode == LIST_IN_LIST) 166 goto lil; 167 if (mode == PUSH_POP_MULT) 168 goto ppm; 169 170 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.map_list_push_pop), &opts); 171 ASSERT_OK(ret, "map_list_push_pop"); 172 ASSERT_OK(opts.retval, "map_list_push_pop retval"); 173 if (!leave_in_map) 174 clear_fields(skel->progs.clear_map_list); 175 176 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.inner_map_list_push_pop), &opts); 177 ASSERT_OK(ret, "inner_map_list_push_pop"); 178 ASSERT_OK(opts.retval, "inner_map_list_push_pop retval"); 179 if (!leave_in_map) 180 clear_fields(skel->progs.clear_inner_map_list); 181 182 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_push_pop), &opts); 183 ASSERT_OK(ret, "global_list_push_pop"); 184 ASSERT_OK(opts.retval, "global_list_push_pop retval"); 185 if (!leave_in_map) 186 clear_fields(skel->progs.clear_global_list); 187 188 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_push_pop_nested), &opts); 189 ASSERT_OK(ret, "global_list_push_pop_nested"); 190 ASSERT_OK(opts.retval, "global_list_push_pop_nested retval"); 191 if (!leave_in_map) 192 clear_fields(skel->progs.clear_global_nested_list); 193 194 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_array_push_pop), &opts); 195 ASSERT_OK(ret, "global_list_array_push_pop"); 196 ASSERT_OK(opts.retval, "global_list_array_push_pop retval"); 197 if (!leave_in_map) 198 clear_fields(skel->progs.clear_global_array_list); 199 200 if (mode == PUSH_POP) 201 goto end; 202 203 ppm: 204 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.map_list_push_pop_multiple), &opts); 205 ASSERT_OK(ret, "map_list_push_pop_multiple"); 206 ASSERT_OK(opts.retval, "map_list_push_pop_multiple retval"); 207 if (!leave_in_map) 208 clear_fields(skel->progs.clear_map_list); 209 210 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.inner_map_list_push_pop_multiple), &opts); 211 ASSERT_OK(ret, "inner_map_list_push_pop_multiple"); 212 ASSERT_OK(opts.retval, "inner_map_list_push_pop_multiple retval"); 213 if (!leave_in_map) 214 clear_fields(skel->progs.clear_inner_map_list); 215 216 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_push_pop_multiple), &opts); 217 ASSERT_OK(ret, "global_list_push_pop_multiple"); 218 ASSERT_OK(opts.retval, "global_list_push_pop_multiple retval"); 219 if (!leave_in_map) 220 clear_fields(skel->progs.clear_global_list); 221 222 if (mode == PUSH_POP_MULT) 223 goto end; 224 225 lil: 226 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.map_list_in_list), &opts); 227 ASSERT_OK(ret, "map_list_in_list"); 228 ASSERT_OK(opts.retval, "map_list_in_list retval"); 229 if (!leave_in_map) 230 clear_fields(skel->progs.clear_map_list); 231 232 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.inner_map_list_in_list), &opts); 233 ASSERT_OK(ret, "inner_map_list_in_list"); 234 ASSERT_OK(opts.retval, "inner_map_list_in_list retval"); 235 if (!leave_in_map) 236 clear_fields(skel->progs.clear_inner_map_list); 237 238 ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_in_list), &opts); 239 ASSERT_OK(ret, "global_list_in_list"); 240 ASSERT_OK(opts.retval, "global_list_in_list retval"); 241 if (!leave_in_map) 242 clear_fields(skel->progs.clear_global_list); 243 end: 244 linked_list__destroy(skel); 245 } 246 247 #define SPIN_LOCK 2 248 #define LIST_HEAD 3 249 #define LIST_NODE 4 250 251 static struct btf *init_btf(void) 252 { 253 int id, lid, hid, nid; 254 struct btf *btf; 255 256 btf = btf__new_empty(); 257 if (!ASSERT_OK_PTR(btf, "btf__new_empty")) 258 return NULL; 259 id = btf__add_int(btf, "int", 4, BTF_INT_SIGNED); 260 if (!ASSERT_EQ(id, 1, "btf__add_int")) 261 goto end; 262 lid = btf__add_struct(btf, "bpf_spin_lock", 4); 263 if (!ASSERT_EQ(lid, SPIN_LOCK, "btf__add_struct bpf_spin_lock")) 264 goto end; 265 hid = btf__add_struct(btf, "bpf_list_head", 16); 266 if (!ASSERT_EQ(hid, LIST_HEAD, "btf__add_struct bpf_list_head")) 267 goto end; 268 nid = btf__add_struct(btf, "bpf_list_node", 24); 269 if (!ASSERT_EQ(nid, LIST_NODE, "btf__add_struct bpf_list_node")) 270 goto end; 271 return btf; 272 end: 273 btf__free(btf); 274 return NULL; 275 } 276 277 static void list_and_rb_node_same_struct(bool refcount_field) 278 { 279 int bpf_rb_node_btf_id, bpf_refcount_btf_id = 0, foo_btf_id; 280 struct btf *btf; 281 int id, err; 282 283 btf = init_btf(); 284 if (!ASSERT_OK_PTR(btf, "init_btf")) 285 return; 286 287 bpf_rb_node_btf_id = btf__add_struct(btf, "bpf_rb_node", 32); 288 if (!ASSERT_GT(bpf_rb_node_btf_id, 0, "btf__add_struct bpf_rb_node")) 289 return; 290 291 if (refcount_field) { 292 bpf_refcount_btf_id = btf__add_struct(btf, "bpf_refcount", 4); 293 if (!ASSERT_GT(bpf_refcount_btf_id, 0, "btf__add_struct bpf_refcount")) 294 return; 295 } 296 297 id = btf__add_struct(btf, "bar", refcount_field ? 60 : 56); 298 if (!ASSERT_GT(id, 0, "btf__add_struct bar")) 299 return; 300 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 301 if (!ASSERT_OK(err, "btf__add_field bar::a")) 302 return; 303 err = btf__add_field(btf, "c", bpf_rb_node_btf_id, 192, 0); 304 if (!ASSERT_OK(err, "btf__add_field bar::c")) 305 return; 306 if (refcount_field) { 307 err = btf__add_field(btf, "ref", bpf_refcount_btf_id, 448, 0); 308 if (!ASSERT_OK(err, "btf__add_field bar::ref")) 309 return; 310 } 311 312 foo_btf_id = btf__add_struct(btf, "foo", 20); 313 if (!ASSERT_GT(foo_btf_id, 0, "btf__add_struct foo")) 314 return; 315 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 316 if (!ASSERT_OK(err, "btf__add_field foo::a")) 317 return; 318 err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0); 319 if (!ASSERT_OK(err, "btf__add_field foo::b")) 320 return; 321 id = btf__add_decl_tag(btf, "contains:bar:a", foo_btf_id, 0); 322 if (!ASSERT_GT(id, 0, "btf__add_decl_tag contains:bar:a")) 323 return; 324 325 err = btf__load_into_kernel(btf); 326 ASSERT_EQ(err, refcount_field ? 0 : -EINVAL, "check btf"); 327 btf__free(btf); 328 } 329 330 static void test_btf(void) 331 { 332 struct btf *btf = NULL; 333 int id, err; 334 335 while (test__start_subtest("btf: too many locks")) { 336 btf = init_btf(); 337 if (!ASSERT_OK_PTR(btf, "init_btf")) 338 break; 339 id = btf__add_struct(btf, "foo", 24); 340 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 341 break; 342 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 343 if (!ASSERT_OK(err, "btf__add_struct foo::a")) 344 break; 345 err = btf__add_field(btf, "b", SPIN_LOCK, 32, 0); 346 if (!ASSERT_OK(err, "btf__add_struct foo::a")) 347 break; 348 err = btf__add_field(btf, "c", LIST_HEAD, 64, 0); 349 if (!ASSERT_OK(err, "btf__add_struct foo::a")) 350 break; 351 352 err = btf__load_into_kernel(btf); 353 ASSERT_EQ(err, -E2BIG, "check btf"); 354 btf__free(btf); 355 break; 356 } 357 358 while (test__start_subtest("btf: missing lock")) { 359 btf = init_btf(); 360 if (!ASSERT_OK_PTR(btf, "init_btf")) 361 break; 362 id = btf__add_struct(btf, "foo", 16); 363 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 364 break; 365 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 366 if (!ASSERT_OK(err, "btf__add_struct foo::a")) 367 break; 368 id = btf__add_decl_tag(btf, "contains:baz:a", 5, 0); 369 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:baz:a")) 370 break; 371 id = btf__add_struct(btf, "baz", 16); 372 if (!ASSERT_EQ(id, 7, "btf__add_struct baz")) 373 break; 374 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 375 if (!ASSERT_OK(err, "btf__add_field baz::a")) 376 break; 377 378 err = btf__load_into_kernel(btf); 379 ASSERT_EQ(err, -EINVAL, "check btf"); 380 btf__free(btf); 381 break; 382 } 383 384 while (test__start_subtest("btf: bad offset")) { 385 btf = init_btf(); 386 if (!ASSERT_OK_PTR(btf, "init_btf")) 387 break; 388 id = btf__add_struct(btf, "foo", 36); 389 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 390 break; 391 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 392 if (!ASSERT_OK(err, "btf__add_field foo::a")) 393 break; 394 err = btf__add_field(btf, "b", LIST_NODE, 0, 0); 395 if (!ASSERT_OK(err, "btf__add_field foo::b")) 396 break; 397 err = btf__add_field(btf, "c", SPIN_LOCK, 0, 0); 398 if (!ASSERT_OK(err, "btf__add_field foo::c")) 399 break; 400 id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0); 401 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:b")) 402 break; 403 404 err = btf__load_into_kernel(btf); 405 ASSERT_EQ(err, -EEXIST, "check btf"); 406 btf__free(btf); 407 break; 408 } 409 410 while (test__start_subtest("btf: missing contains:")) { 411 btf = init_btf(); 412 if (!ASSERT_OK_PTR(btf, "init_btf")) 413 break; 414 id = btf__add_struct(btf, "foo", 24); 415 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 416 break; 417 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 418 if (!ASSERT_OK(err, "btf__add_field foo::a")) 419 break; 420 err = btf__add_field(btf, "b", LIST_HEAD, 64, 0); 421 if (!ASSERT_OK(err, "btf__add_field foo::b")) 422 break; 423 424 err = btf__load_into_kernel(btf); 425 ASSERT_EQ(err, -EINVAL, "check btf"); 426 btf__free(btf); 427 break; 428 } 429 430 while (test__start_subtest("btf: missing struct")) { 431 btf = init_btf(); 432 if (!ASSERT_OK_PTR(btf, "init_btf")) 433 break; 434 id = btf__add_struct(btf, "foo", 24); 435 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 436 break; 437 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 438 if (!ASSERT_OK(err, "btf__add_field foo::a")) 439 break; 440 err = btf__add_field(btf, "b", LIST_HEAD, 64, 0); 441 if (!ASSERT_OK(err, "btf__add_field foo::b")) 442 break; 443 id = btf__add_decl_tag(btf, "contains:bar:bar", 5, 1); 444 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:bar")) 445 break; 446 447 err = btf__load_into_kernel(btf); 448 ASSERT_EQ(err, -ENOENT, "check btf"); 449 btf__free(btf); 450 break; 451 } 452 453 while (test__start_subtest("btf: missing node")) { 454 btf = init_btf(); 455 if (!ASSERT_OK_PTR(btf, "init_btf")) 456 break; 457 id = btf__add_struct(btf, "foo", 24); 458 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 459 break; 460 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 461 if (!ASSERT_OK(err, "btf__add_field foo::a")) 462 break; 463 err = btf__add_field(btf, "b", LIST_HEAD, 64, 0); 464 if (!ASSERT_OK(err, "btf__add_field foo::b")) 465 break; 466 id = btf__add_decl_tag(btf, "contains:foo:c", 5, 1); 467 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:c")) 468 break; 469 470 err = btf__load_into_kernel(btf); 471 btf__free(btf); 472 ASSERT_EQ(err, -ENOENT, "check btf"); 473 break; 474 } 475 476 while (test__start_subtest("btf: node incorrect type")) { 477 btf = init_btf(); 478 if (!ASSERT_OK_PTR(btf, "init_btf")) 479 break; 480 id = btf__add_struct(btf, "foo", 20); 481 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 482 break; 483 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 484 if (!ASSERT_OK(err, "btf__add_field foo::a")) 485 break; 486 err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0); 487 if (!ASSERT_OK(err, "btf__add_field foo::b")) 488 break; 489 id = btf__add_decl_tag(btf, "contains:bar:a", 5, 0); 490 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:a")) 491 break; 492 id = btf__add_struct(btf, "bar", 4); 493 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 494 break; 495 err = btf__add_field(btf, "a", SPIN_LOCK, 0, 0); 496 if (!ASSERT_OK(err, "btf__add_field bar::a")) 497 break; 498 499 err = btf__load_into_kernel(btf); 500 ASSERT_EQ(err, -EINVAL, "check btf"); 501 btf__free(btf); 502 break; 503 } 504 505 while (test__start_subtest("btf: multiple bpf_list_node with name b")) { 506 btf = init_btf(); 507 if (!ASSERT_OK_PTR(btf, "init_btf")) 508 break; 509 id = btf__add_struct(btf, "foo", 52); 510 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 511 break; 512 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 513 if (!ASSERT_OK(err, "btf__add_field foo::a")) 514 break; 515 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 516 if (!ASSERT_OK(err, "btf__add_field foo::b")) 517 break; 518 err = btf__add_field(btf, "b", LIST_NODE, 256, 0); 519 if (!ASSERT_OK(err, "btf__add_field foo::c")) 520 break; 521 err = btf__add_field(btf, "d", SPIN_LOCK, 384, 0); 522 if (!ASSERT_OK(err, "btf__add_field foo::d")) 523 break; 524 id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0); 525 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:b")) 526 break; 527 528 err = btf__load_into_kernel(btf); 529 ASSERT_EQ(err, -EINVAL, "check btf"); 530 btf__free(btf); 531 break; 532 } 533 534 while (test__start_subtest("btf: owning | owned AA cycle")) { 535 btf = init_btf(); 536 if (!ASSERT_OK_PTR(btf, "init_btf")) 537 break; 538 id = btf__add_struct(btf, "foo", 44); 539 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 540 break; 541 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 542 if (!ASSERT_OK(err, "btf__add_field foo::a")) 543 break; 544 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 545 if (!ASSERT_OK(err, "btf__add_field foo::b")) 546 break; 547 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 548 if (!ASSERT_OK(err, "btf__add_field foo::c")) 549 break; 550 id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0); 551 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:foo:b")) 552 break; 553 554 err = btf__load_into_kernel(btf); 555 ASSERT_EQ(err, -ELOOP, "check btf"); 556 btf__free(btf); 557 break; 558 } 559 560 while (test__start_subtest("btf: owning | owned ABA cycle")) { 561 btf = init_btf(); 562 if (!ASSERT_OK_PTR(btf, "init_btf")) 563 break; 564 id = btf__add_struct(btf, "foo", 44); 565 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 566 break; 567 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 568 if (!ASSERT_OK(err, "btf__add_field foo::a")) 569 break; 570 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 571 if (!ASSERT_OK(err, "btf__add_field foo::b")) 572 break; 573 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 574 if (!ASSERT_OK(err, "btf__add_field foo::c")) 575 break; 576 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0); 577 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b")) 578 break; 579 id = btf__add_struct(btf, "bar", 44); 580 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 581 break; 582 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 583 if (!ASSERT_OK(err, "btf__add_field bar::a")) 584 break; 585 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 586 if (!ASSERT_OK(err, "btf__add_field bar::b")) 587 break; 588 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 589 if (!ASSERT_OK(err, "btf__add_field bar::c")) 590 break; 591 id = btf__add_decl_tag(btf, "contains:foo:b", 7, 0); 592 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:foo:b")) 593 break; 594 595 err = btf__load_into_kernel(btf); 596 ASSERT_EQ(err, -ELOOP, "check btf"); 597 btf__free(btf); 598 break; 599 } 600 601 while (test__start_subtest("btf: owning -> owned")) { 602 btf = init_btf(); 603 if (!ASSERT_OK_PTR(btf, "init_btf")) 604 break; 605 id = btf__add_struct(btf, "foo", 28); 606 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 607 break; 608 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 609 if (!ASSERT_OK(err, "btf__add_field foo::a")) 610 break; 611 err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0); 612 if (!ASSERT_OK(err, "btf__add_field foo::b")) 613 break; 614 id = btf__add_decl_tag(btf, "contains:bar:a", 5, 0); 615 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:a")) 616 break; 617 id = btf__add_struct(btf, "bar", 24); 618 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 619 break; 620 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 621 if (!ASSERT_OK(err, "btf__add_field bar::a")) 622 break; 623 624 err = btf__load_into_kernel(btf); 625 ASSERT_EQ(err, 0, "check btf"); 626 btf__free(btf); 627 break; 628 } 629 630 while (test__start_subtest("btf: owning -> owning | owned -> owned")) { 631 btf = init_btf(); 632 if (!ASSERT_OK_PTR(btf, "init_btf")) 633 break; 634 id = btf__add_struct(btf, "foo", 28); 635 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 636 break; 637 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 638 if (!ASSERT_OK(err, "btf__add_field foo::a")) 639 break; 640 err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0); 641 if (!ASSERT_OK(err, "btf__add_field foo::b")) 642 break; 643 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0); 644 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b")) 645 break; 646 id = btf__add_struct(btf, "bar", 44); 647 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 648 break; 649 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 650 if (!ASSERT_OK(err, "btf__add_field bar::a")) 651 break; 652 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 653 if (!ASSERT_OK(err, "btf__add_field bar::b")) 654 break; 655 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 656 if (!ASSERT_OK(err, "btf__add_field bar::c")) 657 break; 658 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0); 659 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a")) 660 break; 661 id = btf__add_struct(btf, "baz", 24); 662 if (!ASSERT_EQ(id, 9, "btf__add_struct baz")) 663 break; 664 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 665 if (!ASSERT_OK(err, "btf__add_field baz:a")) 666 break; 667 668 err = btf__load_into_kernel(btf); 669 ASSERT_EQ(err, 0, "check btf"); 670 btf__free(btf); 671 break; 672 } 673 674 while (test__start_subtest("btf: owning | owned -> owning | owned -> owned")) { 675 btf = init_btf(); 676 if (!ASSERT_OK_PTR(btf, "init_btf")) 677 break; 678 id = btf__add_struct(btf, "foo", 44); 679 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 680 break; 681 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 682 if (!ASSERT_OK(err, "btf__add_field foo::a")) 683 break; 684 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 685 if (!ASSERT_OK(err, "btf__add_field foo::b")) 686 break; 687 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 688 if (!ASSERT_OK(err, "btf__add_field foo::c")) 689 break; 690 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0); 691 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b")) 692 break; 693 id = btf__add_struct(btf, "bar", 44); 694 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 695 break; 696 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 697 if (!ASSERT_OK(err, "btf__add_field bar:a")) 698 break; 699 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 700 if (!ASSERT_OK(err, "btf__add_field bar:b")) 701 break; 702 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 703 if (!ASSERT_OK(err, "btf__add_field bar:c")) 704 break; 705 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0); 706 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a")) 707 break; 708 id = btf__add_struct(btf, "baz", 24); 709 if (!ASSERT_EQ(id, 9, "btf__add_struct baz")) 710 break; 711 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 712 if (!ASSERT_OK(err, "btf__add_field baz:a")) 713 break; 714 715 err = btf__load_into_kernel(btf); 716 ASSERT_EQ(err, -ELOOP, "check btf"); 717 btf__free(btf); 718 break; 719 } 720 721 while (test__start_subtest("btf: owning -> owning | owned -> owning | owned -> owned")) { 722 btf = init_btf(); 723 if (!ASSERT_OK_PTR(btf, "init_btf")) 724 break; 725 id = btf__add_struct(btf, "foo", 20); 726 if (!ASSERT_EQ(id, 5, "btf__add_struct foo")) 727 break; 728 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 729 if (!ASSERT_OK(err, "btf__add_field foo::a")) 730 break; 731 err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0); 732 if (!ASSERT_OK(err, "btf__add_field foo::b")) 733 break; 734 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0); 735 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b")) 736 break; 737 id = btf__add_struct(btf, "bar", 44); 738 if (!ASSERT_EQ(id, 7, "btf__add_struct bar")) 739 break; 740 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 741 if (!ASSERT_OK(err, "btf__add_field bar::a")) 742 break; 743 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 744 if (!ASSERT_OK(err, "btf__add_field bar::b")) 745 break; 746 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 747 if (!ASSERT_OK(err, "btf__add_field bar::c")) 748 break; 749 id = btf__add_decl_tag(btf, "contains:baz:b", 7, 0); 750 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag")) 751 break; 752 id = btf__add_struct(btf, "baz", 44); 753 if (!ASSERT_EQ(id, 9, "btf__add_struct baz")) 754 break; 755 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0); 756 if (!ASSERT_OK(err, "btf__add_field bar::a")) 757 break; 758 err = btf__add_field(btf, "b", LIST_NODE, 128, 0); 759 if (!ASSERT_OK(err, "btf__add_field bar::b")) 760 break; 761 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0); 762 if (!ASSERT_OK(err, "btf__add_field bar::c")) 763 break; 764 id = btf__add_decl_tag(btf, "contains:bam:a", 9, 0); 765 if (!ASSERT_EQ(id, 10, "btf__add_decl_tag contains:bam:a")) 766 break; 767 id = btf__add_struct(btf, "bam", 24); 768 if (!ASSERT_EQ(id, 11, "btf__add_struct bam")) 769 break; 770 err = btf__add_field(btf, "a", LIST_NODE, 0, 0); 771 if (!ASSERT_OK(err, "btf__add_field bam::a")) 772 break; 773 774 err = btf__load_into_kernel(btf); 775 ASSERT_EQ(err, -ELOOP, "check btf"); 776 btf__free(btf); 777 break; 778 } 779 780 while (test__start_subtest("btf: list_node and rb_node in same struct")) { 781 list_and_rb_node_same_struct(true); 782 break; 783 } 784 785 while (test__start_subtest("btf: list_node and rb_node in same struct, no bpf_refcount")) { 786 list_and_rb_node_same_struct(false); 787 break; 788 } 789 } 790 791 void test_linked_list(void) 792 { 793 int i; 794 795 for (i = 0; i < ARRAY_SIZE(linked_list_fail_tests); i++) { 796 if (!test__start_subtest(linked_list_fail_tests[i].prog_name)) 797 continue; 798 test_linked_list_fail_prog(linked_list_fail_tests[i].prog_name, 799 linked_list_fail_tests[i].err_msg); 800 } 801 test_btf(); 802 test_linked_list_success(PUSH_POP, false); 803 test_linked_list_success(PUSH_POP, true); 804 test_linked_list_success(PUSH_POP_MULT, false); 805 test_linked_list_success(PUSH_POP_MULT, true); 806 test_linked_list_success(LIST_IN_LIST, false); 807 test_linked_list_success(LIST_IN_LIST, true); 808 test_linked_list_success(TEST_ALL, false); 809 } 810 811 void test_linked_list_peek(void) 812 { 813 RUN_TESTS(linked_list_peek); 814 } 815