1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ 3 #include <linux/capability.h> 4 #include <stdlib.h> 5 #include <regex.h> 6 #include <test_progs.h> 7 #include <bpf/btf.h> 8 9 #include "autoconf_helper.h" 10 #include "unpriv_helpers.h" 11 #include "cap_helpers.h" 12 13 #define str_has_pfx(str, pfx) \ 14 (strncmp(str, pfx, __builtin_constant_p(pfx) ? sizeof(pfx) - 1 : strlen(pfx)) == 0) 15 16 #define TEST_LOADER_LOG_BUF_SZ 2097152 17 18 #define TEST_TAG_EXPECT_FAILURE "comment:test_expect_failure" 19 #define TEST_TAG_EXPECT_SUCCESS "comment:test_expect_success" 20 #define TEST_TAG_EXPECT_MSG_PFX "comment:test_expect_msg=" 21 #define TEST_TAG_EXPECT_REGEX_PFX "comment:test_expect_regex=" 22 #define TEST_TAG_EXPECT_FAILURE_UNPRIV "comment:test_expect_failure_unpriv" 23 #define TEST_TAG_EXPECT_SUCCESS_UNPRIV "comment:test_expect_success_unpriv" 24 #define TEST_TAG_EXPECT_MSG_PFX_UNPRIV "comment:test_expect_msg_unpriv=" 25 #define TEST_TAG_EXPECT_REGEX_PFX_UNPRIV "comment:test_expect_regex_unpriv=" 26 #define TEST_TAG_LOG_LEVEL_PFX "comment:test_log_level=" 27 #define TEST_TAG_PROG_FLAGS_PFX "comment:test_prog_flags=" 28 #define TEST_TAG_DESCRIPTION_PFX "comment:test_description=" 29 #define TEST_TAG_RETVAL_PFX "comment:test_retval=" 30 #define TEST_TAG_RETVAL_PFX_UNPRIV "comment:test_retval_unpriv=" 31 #define TEST_TAG_AUXILIARY "comment:test_auxiliary" 32 #define TEST_TAG_AUXILIARY_UNPRIV "comment:test_auxiliary_unpriv" 33 #define TEST_BTF_PATH "comment:test_btf_path=" 34 35 /* Warning: duplicated in bpf_misc.h */ 36 #define POINTER_VALUE 0xcafe4all 37 #define TEST_DATA_LEN 64 38 39 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 40 #define EFFICIENT_UNALIGNED_ACCESS 1 41 #else 42 #define EFFICIENT_UNALIGNED_ACCESS 0 43 #endif 44 45 static int sysctl_unpriv_disabled = -1; 46 47 enum mode { 48 PRIV = 1, 49 UNPRIV = 2 50 }; 51 52 struct expect_msg { 53 const char *substr; /* substring match */ 54 const char *regex_str; /* regex-based match */ 55 regex_t regex; 56 }; 57 58 struct test_subspec { 59 char *name; 60 bool expect_failure; 61 struct expect_msg *expect_msgs; 62 size_t expect_msg_cnt; 63 int retval; 64 bool execute; 65 }; 66 67 struct test_spec { 68 const char *prog_name; 69 struct test_subspec priv; 70 struct test_subspec unpriv; 71 const char *btf_custom_path; 72 int log_level; 73 int prog_flags; 74 int mode_mask; 75 bool auxiliary; 76 bool valid; 77 }; 78 79 static int tester_init(struct test_loader *tester) 80 { 81 if (!tester->log_buf) { 82 tester->log_buf_sz = TEST_LOADER_LOG_BUF_SZ; 83 tester->log_buf = calloc(tester->log_buf_sz, 1); 84 if (!ASSERT_OK_PTR(tester->log_buf, "tester_log_buf")) 85 return -ENOMEM; 86 } 87 88 return 0; 89 } 90 91 void test_loader_fini(struct test_loader *tester) 92 { 93 if (!tester) 94 return; 95 96 free(tester->log_buf); 97 } 98 99 static void free_test_spec(struct test_spec *spec) 100 { 101 int i; 102 103 /* Deallocate expect_msgs arrays. */ 104 for (i = 0; i < spec->priv.expect_msg_cnt; i++) 105 if (spec->priv.expect_msgs[i].regex_str) 106 regfree(&spec->priv.expect_msgs[i].regex); 107 for (i = 0; i < spec->unpriv.expect_msg_cnt; i++) 108 if (spec->unpriv.expect_msgs[i].regex_str) 109 regfree(&spec->unpriv.expect_msgs[i].regex); 110 111 free(spec->priv.name); 112 free(spec->unpriv.name); 113 free(spec->priv.expect_msgs); 114 free(spec->unpriv.expect_msgs); 115 116 spec->priv.name = NULL; 117 spec->unpriv.name = NULL; 118 spec->priv.expect_msgs = NULL; 119 spec->unpriv.expect_msgs = NULL; 120 } 121 122 static int push_msg(const char *substr, const char *regex_str, struct test_subspec *subspec) 123 { 124 void *tmp; 125 int regcomp_res; 126 char error_msg[100]; 127 struct expect_msg *msg; 128 129 tmp = realloc(subspec->expect_msgs, 130 (1 + subspec->expect_msg_cnt) * sizeof(struct expect_msg)); 131 if (!tmp) { 132 ASSERT_FAIL("failed to realloc memory for messages\n"); 133 return -ENOMEM; 134 } 135 subspec->expect_msgs = tmp; 136 msg = &subspec->expect_msgs[subspec->expect_msg_cnt]; 137 138 if (substr) { 139 msg->substr = substr; 140 msg->regex_str = NULL; 141 } else { 142 msg->regex_str = regex_str; 143 msg->substr = NULL; 144 regcomp_res = regcomp(&msg->regex, regex_str, REG_EXTENDED|REG_NEWLINE); 145 if (regcomp_res != 0) { 146 regerror(regcomp_res, &msg->regex, error_msg, sizeof(error_msg)); 147 PRINT_FAIL("Regexp compilation error in '%s': '%s'\n", 148 regex_str, error_msg); 149 return -EINVAL; 150 } 151 } 152 153 subspec->expect_msg_cnt += 1; 154 return 0; 155 } 156 157 static int parse_int(const char *str, int *val, const char *name) 158 { 159 char *end; 160 long tmp; 161 162 errno = 0; 163 if (str_has_pfx(str, "0x")) 164 tmp = strtol(str + 2, &end, 16); 165 else 166 tmp = strtol(str, &end, 10); 167 if (errno || end[0] != '\0') { 168 PRINT_FAIL("failed to parse %s from '%s'\n", name, str); 169 return -EINVAL; 170 } 171 *val = tmp; 172 return 0; 173 } 174 175 static int parse_retval(const char *str, int *val, const char *name) 176 { 177 struct { 178 char *name; 179 int val; 180 } named_values[] = { 181 { "INT_MIN" , INT_MIN }, 182 { "POINTER_VALUE", POINTER_VALUE }, 183 { "TEST_DATA_LEN", TEST_DATA_LEN }, 184 }; 185 int i; 186 187 for (i = 0; i < ARRAY_SIZE(named_values); ++i) { 188 if (strcmp(str, named_values[i].name) != 0) 189 continue; 190 *val = named_values[i].val; 191 return 0; 192 } 193 194 return parse_int(str, val, name); 195 } 196 197 static void update_flags(int *flags, int flag, bool clear) 198 { 199 if (clear) 200 *flags &= ~flag; 201 else 202 *flags |= flag; 203 } 204 205 /* Uses btf_decl_tag attributes to describe the expected test 206 * behavior, see bpf_misc.h for detailed description of each attribute 207 * and attribute combinations. 208 */ 209 static int parse_test_spec(struct test_loader *tester, 210 struct bpf_object *obj, 211 struct bpf_program *prog, 212 struct test_spec *spec) 213 { 214 const char *description = NULL; 215 bool has_unpriv_result = false; 216 bool has_unpriv_retval = false; 217 int func_id, i, err = 0; 218 struct btf *btf; 219 220 memset(spec, 0, sizeof(*spec)); 221 222 spec->prog_name = bpf_program__name(prog); 223 spec->prog_flags = testing_prog_flags(); 224 225 btf = bpf_object__btf(obj); 226 if (!btf) { 227 ASSERT_FAIL("BPF object has no BTF"); 228 return -EINVAL; 229 } 230 231 func_id = btf__find_by_name_kind(btf, spec->prog_name, BTF_KIND_FUNC); 232 if (func_id < 0) { 233 ASSERT_FAIL("failed to find FUNC BTF type for '%s'", spec->prog_name); 234 return -EINVAL; 235 } 236 237 for (i = 1; i < btf__type_cnt(btf); i++) { 238 const char *s, *val, *msg; 239 const struct btf_type *t; 240 bool clear; 241 int flags; 242 243 t = btf__type_by_id(btf, i); 244 if (!btf_is_decl_tag(t)) 245 continue; 246 247 if (t->type != func_id || btf_decl_tag(t)->component_idx != -1) 248 continue; 249 250 s = btf__str_by_offset(btf, t->name_off); 251 if (str_has_pfx(s, TEST_TAG_DESCRIPTION_PFX)) { 252 description = s + sizeof(TEST_TAG_DESCRIPTION_PFX) - 1; 253 } else if (strcmp(s, TEST_TAG_EXPECT_FAILURE) == 0) { 254 spec->priv.expect_failure = true; 255 spec->mode_mask |= PRIV; 256 } else if (strcmp(s, TEST_TAG_EXPECT_SUCCESS) == 0) { 257 spec->priv.expect_failure = false; 258 spec->mode_mask |= PRIV; 259 } else if (strcmp(s, TEST_TAG_EXPECT_FAILURE_UNPRIV) == 0) { 260 spec->unpriv.expect_failure = true; 261 spec->mode_mask |= UNPRIV; 262 has_unpriv_result = true; 263 } else if (strcmp(s, TEST_TAG_EXPECT_SUCCESS_UNPRIV) == 0) { 264 spec->unpriv.expect_failure = false; 265 spec->mode_mask |= UNPRIV; 266 has_unpriv_result = true; 267 } else if (strcmp(s, TEST_TAG_AUXILIARY) == 0) { 268 spec->auxiliary = true; 269 spec->mode_mask |= PRIV; 270 } else if (strcmp(s, TEST_TAG_AUXILIARY_UNPRIV) == 0) { 271 spec->auxiliary = true; 272 spec->mode_mask |= UNPRIV; 273 } else if (str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX)) { 274 msg = s + sizeof(TEST_TAG_EXPECT_MSG_PFX) - 1; 275 err = push_msg(msg, NULL, &spec->priv); 276 if (err) 277 goto cleanup; 278 spec->mode_mask |= PRIV; 279 } else if (str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX_UNPRIV)) { 280 msg = s + sizeof(TEST_TAG_EXPECT_MSG_PFX_UNPRIV) - 1; 281 err = push_msg(msg, NULL, &spec->unpriv); 282 if (err) 283 goto cleanup; 284 spec->mode_mask |= UNPRIV; 285 } else if (str_has_pfx(s, TEST_TAG_EXPECT_REGEX_PFX)) { 286 msg = s + sizeof(TEST_TAG_EXPECT_REGEX_PFX) - 1; 287 err = push_msg(NULL, msg, &spec->priv); 288 if (err) 289 goto cleanup; 290 spec->mode_mask |= PRIV; 291 } else if (str_has_pfx(s, TEST_TAG_EXPECT_REGEX_PFX_UNPRIV)) { 292 msg = s + sizeof(TEST_TAG_EXPECT_REGEX_PFX_UNPRIV) - 1; 293 err = push_msg(NULL, msg, &spec->unpriv); 294 if (err) 295 goto cleanup; 296 spec->mode_mask |= UNPRIV; 297 } else if (str_has_pfx(s, TEST_TAG_RETVAL_PFX)) { 298 val = s + sizeof(TEST_TAG_RETVAL_PFX) - 1; 299 err = parse_retval(val, &spec->priv.retval, "__retval"); 300 if (err) 301 goto cleanup; 302 spec->priv.execute = true; 303 spec->mode_mask |= PRIV; 304 } else if (str_has_pfx(s, TEST_TAG_RETVAL_PFX_UNPRIV)) { 305 val = s + sizeof(TEST_TAG_RETVAL_PFX_UNPRIV) - 1; 306 err = parse_retval(val, &spec->unpriv.retval, "__retval_unpriv"); 307 if (err) 308 goto cleanup; 309 spec->mode_mask |= UNPRIV; 310 spec->unpriv.execute = true; 311 has_unpriv_retval = true; 312 } else if (str_has_pfx(s, TEST_TAG_LOG_LEVEL_PFX)) { 313 val = s + sizeof(TEST_TAG_LOG_LEVEL_PFX) - 1; 314 err = parse_int(val, &spec->log_level, "test log level"); 315 if (err) 316 goto cleanup; 317 } else if (str_has_pfx(s, TEST_TAG_PROG_FLAGS_PFX)) { 318 val = s + sizeof(TEST_TAG_PROG_FLAGS_PFX) - 1; 319 320 clear = val[0] == '!'; 321 if (clear) 322 val++; 323 324 if (strcmp(val, "BPF_F_STRICT_ALIGNMENT") == 0) { 325 update_flags(&spec->prog_flags, BPF_F_STRICT_ALIGNMENT, clear); 326 } else if (strcmp(val, "BPF_F_ANY_ALIGNMENT") == 0) { 327 update_flags(&spec->prog_flags, BPF_F_ANY_ALIGNMENT, clear); 328 } else if (strcmp(val, "BPF_F_TEST_RND_HI32") == 0) { 329 update_flags(&spec->prog_flags, BPF_F_TEST_RND_HI32, clear); 330 } else if (strcmp(val, "BPF_F_TEST_STATE_FREQ") == 0) { 331 update_flags(&spec->prog_flags, BPF_F_TEST_STATE_FREQ, clear); 332 } else if (strcmp(val, "BPF_F_SLEEPABLE") == 0) { 333 update_flags(&spec->prog_flags, BPF_F_SLEEPABLE, clear); 334 } else if (strcmp(val, "BPF_F_XDP_HAS_FRAGS") == 0) { 335 update_flags(&spec->prog_flags, BPF_F_XDP_HAS_FRAGS, clear); 336 } else if (strcmp(val, "BPF_F_TEST_REG_INVARIANTS") == 0) { 337 update_flags(&spec->prog_flags, BPF_F_TEST_REG_INVARIANTS, clear); 338 } else /* assume numeric value */ { 339 err = parse_int(val, &flags, "test prog flags"); 340 if (err) 341 goto cleanup; 342 update_flags(&spec->prog_flags, flags, clear); 343 } 344 } else if (str_has_pfx(s, TEST_BTF_PATH)) { 345 spec->btf_custom_path = s + sizeof(TEST_BTF_PATH) - 1; 346 } 347 } 348 349 if (spec->mode_mask == 0) 350 spec->mode_mask = PRIV; 351 352 if (!description) 353 description = spec->prog_name; 354 355 if (spec->mode_mask & PRIV) { 356 spec->priv.name = strdup(description); 357 if (!spec->priv.name) { 358 PRINT_FAIL("failed to allocate memory for priv.name\n"); 359 err = -ENOMEM; 360 goto cleanup; 361 } 362 } 363 364 if (spec->mode_mask & UNPRIV) { 365 int descr_len = strlen(description); 366 const char *suffix = " @unpriv"; 367 char *name; 368 369 name = malloc(descr_len + strlen(suffix) + 1); 370 if (!name) { 371 PRINT_FAIL("failed to allocate memory for unpriv.name\n"); 372 err = -ENOMEM; 373 goto cleanup; 374 } 375 376 strcpy(name, description); 377 strcpy(&name[descr_len], suffix); 378 spec->unpriv.name = name; 379 } 380 381 if (spec->mode_mask & (PRIV | UNPRIV)) { 382 if (!has_unpriv_result) 383 spec->unpriv.expect_failure = spec->priv.expect_failure; 384 385 if (!has_unpriv_retval) { 386 spec->unpriv.retval = spec->priv.retval; 387 spec->unpriv.execute = spec->priv.execute; 388 } 389 390 if (!spec->unpriv.expect_msgs) { 391 for (i = 0; i < spec->priv.expect_msg_cnt; i++) { 392 struct expect_msg *msg = &spec->priv.expect_msgs[i]; 393 394 err = push_msg(msg->substr, msg->regex_str, &spec->unpriv); 395 if (err) 396 goto cleanup; 397 } 398 } 399 } 400 401 spec->valid = true; 402 403 return 0; 404 405 cleanup: 406 free_test_spec(spec); 407 return err; 408 } 409 410 static void prepare_case(struct test_loader *tester, 411 struct test_spec *spec, 412 struct bpf_object *obj, 413 struct bpf_program *prog) 414 { 415 int min_log_level = 0, prog_flags; 416 417 if (env.verbosity > VERBOSE_NONE) 418 min_log_level = 1; 419 if (env.verbosity > VERBOSE_VERY) 420 min_log_level = 2; 421 422 bpf_program__set_log_buf(prog, tester->log_buf, tester->log_buf_sz); 423 424 /* Make sure we set at least minimal log level, unless test requires 425 * even higher level already. Make sure to preserve independent log 426 * level 4 (verifier stats), though. 427 */ 428 if ((spec->log_level & 3) < min_log_level) 429 bpf_program__set_log_level(prog, (spec->log_level & 4) | min_log_level); 430 else 431 bpf_program__set_log_level(prog, spec->log_level); 432 433 prog_flags = bpf_program__flags(prog); 434 bpf_program__set_flags(prog, prog_flags | spec->prog_flags); 435 436 tester->log_buf[0] = '\0'; 437 tester->next_match_pos = 0; 438 } 439 440 static void emit_verifier_log(const char *log_buf, bool force) 441 { 442 if (!force && env.verbosity == VERBOSE_NONE) 443 return; 444 fprintf(stdout, "VERIFIER LOG:\n=============\n%s=============\n", log_buf); 445 } 446 447 static void validate_case(struct test_loader *tester, 448 struct test_subspec *subspec, 449 struct bpf_object *obj, 450 struct bpf_program *prog, 451 int load_err) 452 { 453 int i, j, err; 454 char *match; 455 regmatch_t reg_match[1]; 456 457 for (i = 0; i < subspec->expect_msg_cnt; i++) { 458 struct expect_msg *msg = &subspec->expect_msgs[i]; 459 460 if (msg->substr) { 461 match = strstr(tester->log_buf + tester->next_match_pos, msg->substr); 462 if (match) 463 tester->next_match_pos = match - tester->log_buf + strlen(msg->substr); 464 } else { 465 err = regexec(&msg->regex, 466 tester->log_buf + tester->next_match_pos, 1, reg_match, 0); 467 if (err == 0) { 468 match = tester->log_buf + tester->next_match_pos + reg_match[0].rm_so; 469 tester->next_match_pos += reg_match[0].rm_eo; 470 } else { 471 match = NULL; 472 } 473 } 474 475 if (!ASSERT_OK_PTR(match, "expect_msg")) { 476 if (env.verbosity == VERBOSE_NONE) 477 emit_verifier_log(tester->log_buf, true /*force*/); 478 for (j = 0; j <= i; j++) { 479 msg = &subspec->expect_msgs[j]; 480 fprintf(stderr, "%s %s: '%s'\n", 481 j < i ? "MATCHED " : "EXPECTED", 482 msg->substr ? "SUBSTR" : " REGEX", 483 msg->substr ?: msg->regex_str); 484 } 485 return; 486 } 487 } 488 } 489 490 struct cap_state { 491 __u64 old_caps; 492 bool initialized; 493 }; 494 495 static int drop_capabilities(struct cap_state *caps) 496 { 497 const __u64 caps_to_drop = (1ULL << CAP_SYS_ADMIN | 1ULL << CAP_NET_ADMIN | 498 1ULL << CAP_PERFMON | 1ULL << CAP_BPF); 499 int err; 500 501 err = cap_disable_effective(caps_to_drop, &caps->old_caps); 502 if (err) { 503 PRINT_FAIL("failed to drop capabilities: %i, %s\n", err, strerror(err)); 504 return err; 505 } 506 507 caps->initialized = true; 508 return 0; 509 } 510 511 static int restore_capabilities(struct cap_state *caps) 512 { 513 int err; 514 515 if (!caps->initialized) 516 return 0; 517 518 err = cap_enable_effective(caps->old_caps, NULL); 519 if (err) 520 PRINT_FAIL("failed to restore capabilities: %i, %s\n", err, strerror(err)); 521 caps->initialized = false; 522 return err; 523 } 524 525 static bool can_execute_unpriv(struct test_loader *tester, struct test_spec *spec) 526 { 527 if (sysctl_unpriv_disabled < 0) 528 sysctl_unpriv_disabled = get_unpriv_disabled() ? 1 : 0; 529 if (sysctl_unpriv_disabled) 530 return false; 531 if ((spec->prog_flags & BPF_F_ANY_ALIGNMENT) && !EFFICIENT_UNALIGNED_ACCESS) 532 return false; 533 return true; 534 } 535 536 static bool is_unpriv_capable_map(struct bpf_map *map) 537 { 538 enum bpf_map_type type; 539 __u32 flags; 540 541 type = bpf_map__type(map); 542 543 switch (type) { 544 case BPF_MAP_TYPE_HASH: 545 case BPF_MAP_TYPE_PERCPU_HASH: 546 case BPF_MAP_TYPE_HASH_OF_MAPS: 547 flags = bpf_map__map_flags(map); 548 return !(flags & BPF_F_ZERO_SEED); 549 case BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE: 550 case BPF_MAP_TYPE_ARRAY: 551 case BPF_MAP_TYPE_RINGBUF: 552 case BPF_MAP_TYPE_PROG_ARRAY: 553 case BPF_MAP_TYPE_CGROUP_ARRAY: 554 case BPF_MAP_TYPE_PERCPU_ARRAY: 555 case BPF_MAP_TYPE_USER_RINGBUF: 556 case BPF_MAP_TYPE_ARRAY_OF_MAPS: 557 case BPF_MAP_TYPE_CGROUP_STORAGE: 558 case BPF_MAP_TYPE_PERF_EVENT_ARRAY: 559 return true; 560 default: 561 return false; 562 } 563 } 564 565 static int do_prog_test_run(int fd_prog, int *retval, bool empty_opts) 566 { 567 __u8 tmp_out[TEST_DATA_LEN << 2] = {}; 568 __u8 tmp_in[TEST_DATA_LEN] = {}; 569 int err, saved_errno; 570 LIBBPF_OPTS(bpf_test_run_opts, topts, 571 .data_in = tmp_in, 572 .data_size_in = sizeof(tmp_in), 573 .data_out = tmp_out, 574 .data_size_out = sizeof(tmp_out), 575 .repeat = 1, 576 ); 577 578 if (empty_opts) { 579 memset(&topts, 0, sizeof(struct bpf_test_run_opts)); 580 topts.sz = sizeof(struct bpf_test_run_opts); 581 } 582 err = bpf_prog_test_run_opts(fd_prog, &topts); 583 saved_errno = errno; 584 585 if (err) { 586 PRINT_FAIL("FAIL: Unexpected bpf_prog_test_run error: %d (%s) ", 587 saved_errno, strerror(saved_errno)); 588 return err; 589 } 590 591 ASSERT_OK(0, "bpf_prog_test_run"); 592 *retval = topts.retval; 593 594 return 0; 595 } 596 597 static bool should_do_test_run(struct test_spec *spec, struct test_subspec *subspec) 598 { 599 if (!subspec->execute) 600 return false; 601 602 if (subspec->expect_failure) 603 return false; 604 605 if ((spec->prog_flags & BPF_F_ANY_ALIGNMENT) && !EFFICIENT_UNALIGNED_ACCESS) { 606 if (env.verbosity != VERBOSE_NONE) 607 printf("alignment prevents execution\n"); 608 return false; 609 } 610 611 return true; 612 } 613 614 /* this function is forced noinline and has short generic name to look better 615 * in test_progs output (in case of a failure) 616 */ 617 static noinline 618 void run_subtest(struct test_loader *tester, 619 struct bpf_object_open_opts *open_opts, 620 const void *obj_bytes, 621 size_t obj_byte_cnt, 622 struct test_spec *specs, 623 struct test_spec *spec, 624 bool unpriv) 625 { 626 struct test_subspec *subspec = unpriv ? &spec->unpriv : &spec->priv; 627 struct bpf_program *tprog = NULL, *tprog_iter; 628 struct test_spec *spec_iter; 629 struct cap_state caps = {}; 630 struct bpf_object *tobj; 631 struct bpf_map *map; 632 int retval, err, i; 633 bool should_load; 634 635 if (!test__start_subtest(subspec->name)) 636 return; 637 638 if (unpriv) { 639 if (!can_execute_unpriv(tester, spec)) { 640 test__skip(); 641 test__end_subtest(); 642 return; 643 } 644 if (drop_capabilities(&caps)) { 645 test__end_subtest(); 646 return; 647 } 648 } 649 650 /* Implicitly reset to NULL if next test case doesn't specify */ 651 open_opts->btf_custom_path = spec->btf_custom_path; 652 653 tobj = bpf_object__open_mem(obj_bytes, obj_byte_cnt, open_opts); 654 if (!ASSERT_OK_PTR(tobj, "obj_open_mem")) /* shouldn't happen */ 655 goto subtest_cleanup; 656 657 i = 0; 658 bpf_object__for_each_program(tprog_iter, tobj) { 659 spec_iter = &specs[i++]; 660 should_load = false; 661 662 if (spec_iter->valid) { 663 if (strcmp(bpf_program__name(tprog_iter), spec->prog_name) == 0) { 664 tprog = tprog_iter; 665 should_load = true; 666 } 667 668 if (spec_iter->auxiliary && 669 spec_iter->mode_mask & (unpriv ? UNPRIV : PRIV)) 670 should_load = true; 671 } 672 673 bpf_program__set_autoload(tprog_iter, should_load); 674 } 675 676 prepare_case(tester, spec, tobj, tprog); 677 678 /* By default bpf_object__load() automatically creates all 679 * maps declared in the skeleton. Some map types are only 680 * allowed in priv mode. Disable autoload for such maps in 681 * unpriv mode. 682 */ 683 bpf_object__for_each_map(map, tobj) 684 bpf_map__set_autocreate(map, !unpriv || is_unpriv_capable_map(map)); 685 686 err = bpf_object__load(tobj); 687 if (subspec->expect_failure) { 688 if (!ASSERT_ERR(err, "unexpected_load_success")) { 689 emit_verifier_log(tester->log_buf, false /*force*/); 690 goto tobj_cleanup; 691 } 692 } else { 693 if (!ASSERT_OK(err, "unexpected_load_failure")) { 694 emit_verifier_log(tester->log_buf, true /*force*/); 695 goto tobj_cleanup; 696 } 697 } 698 699 emit_verifier_log(tester->log_buf, false /*force*/); 700 validate_case(tester, subspec, tobj, tprog, err); 701 702 if (should_do_test_run(spec, subspec)) { 703 /* For some reason test_verifier executes programs 704 * with all capabilities restored. Do the same here. 705 */ 706 if (restore_capabilities(&caps)) 707 goto tobj_cleanup; 708 709 if (tester->pre_execution_cb) { 710 err = tester->pre_execution_cb(tobj); 711 if (err) { 712 PRINT_FAIL("pre_execution_cb failed: %d\n", err); 713 goto tobj_cleanup; 714 } 715 } 716 717 do_prog_test_run(bpf_program__fd(tprog), &retval, 718 bpf_program__type(tprog) == BPF_PROG_TYPE_SYSCALL ? true : false); 719 if (retval != subspec->retval && subspec->retval != POINTER_VALUE) { 720 PRINT_FAIL("Unexpected retval: %d != %d\n", retval, subspec->retval); 721 goto tobj_cleanup; 722 } 723 } 724 725 tobj_cleanup: 726 bpf_object__close(tobj); 727 subtest_cleanup: 728 test__end_subtest(); 729 restore_capabilities(&caps); 730 } 731 732 static void process_subtest(struct test_loader *tester, 733 const char *skel_name, 734 skel_elf_bytes_fn elf_bytes_factory) 735 { 736 LIBBPF_OPTS(bpf_object_open_opts, open_opts, .object_name = skel_name); 737 struct test_spec *specs = NULL; 738 struct bpf_object *obj = NULL; 739 struct bpf_program *prog; 740 const void *obj_bytes; 741 int err, i, nr_progs; 742 size_t obj_byte_cnt; 743 744 if (tester_init(tester) < 0) 745 return; /* failed to initialize tester */ 746 747 obj_bytes = elf_bytes_factory(&obj_byte_cnt); 748 obj = bpf_object__open_mem(obj_bytes, obj_byte_cnt, &open_opts); 749 if (!ASSERT_OK_PTR(obj, "obj_open_mem")) 750 return; 751 752 nr_progs = 0; 753 bpf_object__for_each_program(prog, obj) 754 ++nr_progs; 755 756 specs = calloc(nr_progs, sizeof(struct test_spec)); 757 if (!ASSERT_OK_PTR(specs, "specs_alloc")) 758 return; 759 760 i = 0; 761 bpf_object__for_each_program(prog, obj) { 762 /* ignore tests for which we can't derive test specification */ 763 err = parse_test_spec(tester, obj, prog, &specs[i++]); 764 if (err) 765 PRINT_FAIL("Can't parse test spec for program '%s'\n", 766 bpf_program__name(prog)); 767 } 768 769 i = 0; 770 bpf_object__for_each_program(prog, obj) { 771 struct test_spec *spec = &specs[i++]; 772 773 if (!spec->valid || spec->auxiliary) 774 continue; 775 776 if (spec->mode_mask & PRIV) 777 run_subtest(tester, &open_opts, obj_bytes, obj_byte_cnt, 778 specs, spec, false); 779 if (spec->mode_mask & UNPRIV) 780 run_subtest(tester, &open_opts, obj_bytes, obj_byte_cnt, 781 specs, spec, true); 782 783 } 784 785 for (i = 0; i < nr_progs; ++i) 786 free_test_spec(&specs[i]); 787 free(specs); 788 bpf_object__close(obj); 789 } 790 791 void test_loader__run_subtests(struct test_loader *tester, 792 const char *skel_name, 793 skel_elf_bytes_fn elf_bytes_factory) 794 { 795 /* see comment in run_subtest() for why we do this function nesting */ 796 process_subtest(tester, skel_name, elf_bytes_factory); 797 } 798