1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 /* Copyright (C) 2019 Netronome Systems, Inc. */ 3 /* Copyright (C) 2020 Facebook, Inc. */ 4 #include <ctype.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <errno.h> 8 #include <sys/mman.h> 9 #include <alloca.h> 10 #include <bpf/bpf.h> 11 #include <bpf/btf.h> 12 #include <bpf/libbpf.h> 13 #include "disasm.h" 14 #include "test_progs.h" 15 #include "testing_helpers.h" 16 #include <linux/membarrier.h> 17 #include <linux/userfaultfd.h> 18 19 int parse_num_list(const char *s, bool **num_set, int *num_set_len) 20 { 21 int i, set_len = 0, new_len, num, start = 0, end = -1; 22 bool *set = NULL, *tmp, parsing_end = false; 23 char *next; 24 25 while (s[0]) { 26 errno = 0; 27 num = strtol(s, &next, 10); 28 if (errno) 29 return -errno; 30 31 if (parsing_end) 32 end = num; 33 else 34 start = num; 35 36 if (!parsing_end && *next == '-') { 37 s = next + 1; 38 parsing_end = true; 39 continue; 40 } else if (*next == ',') { 41 parsing_end = false; 42 s = next + 1; 43 end = num; 44 } else if (*next == '\0') { 45 parsing_end = false; 46 s = next; 47 end = num; 48 } else { 49 return -EINVAL; 50 } 51 52 if (start > end) 53 return -EINVAL; 54 55 if (end + 1 > set_len) { 56 new_len = end + 1; 57 tmp = realloc(set, new_len); 58 if (!tmp) { 59 free(set); 60 return -ENOMEM; 61 } 62 for (i = set_len; i < start; i++) 63 tmp[i] = false; 64 set = tmp; 65 set_len = new_len; 66 } 67 for (i = start; i <= end; i++) 68 set[i] = true; 69 } 70 71 if (!set || parsing_end) 72 return -EINVAL; 73 74 *num_set = set; 75 *num_set_len = set_len; 76 77 return 0; 78 } 79 80 static int do_insert_test(struct test_filter_set *set, 81 char *test_str, 82 char *subtest_str) 83 { 84 struct test_filter *tmp, *test; 85 char **ctmp; 86 int i; 87 88 for (i = 0; i < set->cnt; i++) { 89 test = &set->tests[i]; 90 91 if (strcmp(test_str, test->name) == 0) { 92 free(test_str); 93 goto subtest; 94 } 95 } 96 97 tmp = realloc(set->tests, sizeof(*test) * (set->cnt + 1)); 98 if (!tmp) 99 return -ENOMEM; 100 101 set->tests = tmp; 102 test = &set->tests[set->cnt]; 103 104 test->name = test_str; 105 test->subtests = NULL; 106 test->subtest_cnt = 0; 107 108 set->cnt++; 109 110 subtest: 111 if (!subtest_str) 112 return 0; 113 114 for (i = 0; i < test->subtest_cnt; i++) { 115 if (strcmp(subtest_str, test->subtests[i]) == 0) { 116 free(subtest_str); 117 return 0; 118 } 119 } 120 121 ctmp = realloc(test->subtests, 122 sizeof(*test->subtests) * (test->subtest_cnt + 1)); 123 if (!ctmp) 124 return -ENOMEM; 125 126 test->subtests = ctmp; 127 test->subtests[test->subtest_cnt] = subtest_str; 128 129 test->subtest_cnt++; 130 131 return 0; 132 } 133 134 static int insert_test(struct test_filter_set *set, 135 char *test_spec, 136 bool is_glob_pattern) 137 { 138 char *pattern, *subtest_str, *ext_test_str, *ext_subtest_str = NULL; 139 int glob_chars = 0; 140 141 if (is_glob_pattern) { 142 pattern = "%s"; 143 } else { 144 pattern = "*%s*"; 145 glob_chars = 2; 146 } 147 148 subtest_str = strchr(test_spec, '/'); 149 if (subtest_str) { 150 *subtest_str = '\0'; 151 subtest_str += 1; 152 } 153 154 ext_test_str = malloc(strlen(test_spec) + glob_chars + 1); 155 if (!ext_test_str) 156 goto err; 157 158 sprintf(ext_test_str, pattern, test_spec); 159 160 if (subtest_str) { 161 ext_subtest_str = malloc(strlen(subtest_str) + glob_chars + 1); 162 if (!ext_subtest_str) 163 goto err; 164 165 sprintf(ext_subtest_str, pattern, subtest_str); 166 } 167 168 return do_insert_test(set, ext_test_str, ext_subtest_str); 169 170 err: 171 free(ext_test_str); 172 free(ext_subtest_str); 173 174 return -ENOMEM; 175 } 176 177 int parse_test_list_file(const char *path, 178 struct test_filter_set *set, 179 bool is_glob_pattern) 180 { 181 char *buf = NULL, *capture_start, *capture_end, *scan_end; 182 size_t buflen = 0; 183 int err = 0; 184 FILE *f; 185 186 f = fopen(path, "r"); 187 if (!f) { 188 err = -errno; 189 fprintf(stderr, "Failed to open '%s': %d\n", path, err); 190 return err; 191 } 192 193 while (getline(&buf, &buflen, f) != -1) { 194 capture_start = buf; 195 196 while (isspace(*capture_start)) 197 ++capture_start; 198 199 capture_end = capture_start; 200 scan_end = capture_start; 201 202 while (*scan_end && *scan_end != '#') { 203 if (!isspace(*scan_end)) 204 capture_end = scan_end; 205 206 ++scan_end; 207 } 208 209 if (capture_end == capture_start) 210 continue; 211 212 *(++capture_end) = '\0'; 213 214 err = insert_test(set, capture_start, is_glob_pattern); 215 if (err) 216 break; 217 } 218 219 free(buf); 220 fclose(f); 221 return err; 222 } 223 224 int parse_test_list(const char *s, 225 struct test_filter_set *set, 226 bool is_glob_pattern) 227 { 228 char *input, *state = NULL, *test_spec; 229 int err = 0, cnt = 0; 230 231 input = strdup(s); 232 if (!input) 233 return -ENOMEM; 234 235 while ((test_spec = strtok_r(cnt++ ? NULL : input, ",", &state))) { 236 err = insert_test(set, test_spec, is_glob_pattern); 237 if (err) 238 break; 239 } 240 241 free(input); 242 return err; 243 } 244 245 __u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info) 246 { 247 __u32 info_len = sizeof(*info); 248 int err; 249 250 memset(info, 0, sizeof(*info)); 251 err = bpf_link_get_info_by_fd(bpf_link__fd(link), info, &info_len); 252 if (err) { 253 printf("failed to get link info: %d\n", -errno); 254 return 0; 255 } 256 return info->prog_id; 257 } 258 259 int extra_prog_load_log_flags = 0; 260 261 int testing_prog_flags(void) 262 { 263 static int cached_flags = -1; 264 static int prog_flags[] = { BPF_F_TEST_RND_HI32, BPF_F_TEST_REG_INVARIANTS }; 265 static struct bpf_insn insns[] = { 266 BPF_MOV64_IMM(BPF_REG_0, 0), 267 BPF_EXIT_INSN(), 268 }; 269 int insn_cnt = ARRAY_SIZE(insns), i, fd, flags = 0; 270 LIBBPF_OPTS(bpf_prog_load_opts, opts); 271 272 if (cached_flags >= 0) 273 return cached_flags; 274 275 for (i = 0; i < ARRAY_SIZE(prog_flags); i++) { 276 opts.prog_flags = prog_flags[i]; 277 fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "flag-test", "GPL", 278 insns, insn_cnt, &opts); 279 if (fd >= 0) { 280 flags |= prog_flags[i]; 281 close(fd); 282 } 283 } 284 285 cached_flags = flags; 286 return cached_flags; 287 } 288 289 int bpf_prog_test_load(const char *file, enum bpf_prog_type type, 290 struct bpf_object **pobj, int *prog_fd) 291 { 292 LIBBPF_OPTS(bpf_object_open_opts, opts, 293 .kernel_log_level = extra_prog_load_log_flags, 294 ); 295 struct bpf_object *obj; 296 struct bpf_program *prog; 297 int err; 298 299 obj = bpf_object__open_file(file, &opts); 300 if (!obj) 301 return -errno; 302 303 prog = bpf_object__next_program(obj, NULL); 304 if (!prog) { 305 err = -ENOENT; 306 goto err_out; 307 } 308 309 if (type != BPF_PROG_TYPE_UNSPEC && bpf_program__type(prog) != type) 310 bpf_program__set_type(prog, type); 311 312 bpf_program__add_flags(prog, testing_prog_flags()); 313 314 err = bpf_object__load(obj); 315 if (err) 316 goto err_out; 317 318 *pobj = obj; 319 *prog_fd = bpf_program__fd(prog); 320 321 return 0; 322 err_out: 323 bpf_object__close(obj); 324 return err; 325 } 326 327 int bpf_test_load_program(enum bpf_prog_type type, const struct bpf_insn *insns, 328 size_t insns_cnt, const char *license, 329 __u32 kern_version, char *log_buf, 330 size_t log_buf_sz) 331 { 332 LIBBPF_OPTS(bpf_prog_load_opts, opts, 333 .kern_version = kern_version, 334 .prog_flags = testing_prog_flags(), 335 .log_level = extra_prog_load_log_flags, 336 .log_buf = log_buf, 337 .log_size = log_buf_sz, 338 ); 339 340 return bpf_prog_load(type, NULL, license, insns, insns_cnt, &opts); 341 } 342 343 __u64 read_perf_max_sample_freq(void) 344 { 345 __u64 sample_freq = 5000; /* fallback to 5000 on error */ 346 FILE *f; 347 348 f = fopen("/proc/sys/kernel/perf_event_max_sample_rate", "r"); 349 if (f == NULL) { 350 printf("Failed to open /proc/sys/kernel/perf_event_max_sample_rate: err %d\n" 351 "return default value: 5000\n", -errno); 352 return sample_freq; 353 } 354 if (fscanf(f, "%llu", &sample_freq) != 1) { 355 printf("Failed to parse /proc/sys/kernel/perf_event_max_sample_rate: err %d\n" 356 "return default value: 5000\n", -errno); 357 } 358 359 fclose(f); 360 return sample_freq; 361 } 362 363 int finit_module(int fd, const char *param_values, int flags) 364 { 365 return syscall(__NR_finit_module, fd, param_values, flags); 366 } 367 368 int delete_module(const char *name, int flags) 369 { 370 return syscall(__NR_delete_module, name, flags); 371 } 372 373 int try_unload_module(const char *name, int retries, bool verbose) 374 { 375 int ret, cnt = 0; 376 377 if (kern_sync_rcu()) 378 fprintf(stdout, "Failed to trigger kernel-side RCU sync!\n"); 379 380 for (;;) { 381 ret = delete_module(name, 0); 382 if (!ret || errno != EAGAIN) 383 break; 384 if (++cnt > retries) { 385 fprintf(stdout, "Unload of %s timed out\n", name); 386 break; 387 } 388 usleep(100); 389 } 390 391 if (ret) { 392 if (errno == ENOENT) { 393 if (verbose) 394 fprintf(stdout, "%s.ko is already unloaded.\n", name); 395 return -1; 396 } 397 fprintf(stdout, "Failed to unload %s.ko from kernel: %d\n", name, -errno); 398 return -1; 399 } 400 if (verbose) 401 fprintf(stdout, "Successfully unloaded %s.ko.\n", name); 402 return 0; 403 } 404 405 int unload_module(const char *name, bool verbose) 406 { 407 return try_unload_module(name, 10000, verbose); 408 } 409 410 static int __load_module(const char *path, const char *param_values, bool verbose) 411 { 412 int fd; 413 414 if (verbose) 415 fprintf(stdout, "Loading %s...\n", path); 416 417 fd = open(path, O_RDONLY); 418 if (fd < 0) { 419 fprintf(stdout, "Can't find %s kernel module: %d\n", path, -errno); 420 return -ENOENT; 421 } 422 if (finit_module(fd, param_values, 0)) { 423 fprintf(stdout, "Failed to load %s into the kernel: %d\n", path, -errno); 424 close(fd); 425 return -EINVAL; 426 } 427 close(fd); 428 429 if (verbose) 430 fprintf(stdout, "Successfully loaded %s.\n", path); 431 return 0; 432 } 433 434 int load_module_params(const char *path, const char *param_values, bool verbose) 435 { 436 return __load_module(path, param_values, verbose); 437 } 438 439 int load_module(const char *path, bool verbose) 440 { 441 return __load_module(path, "", verbose); 442 } 443 444 int unload_bpf_testmod(bool verbose) 445 { 446 return unload_module("bpf_testmod", verbose); 447 } 448 449 int load_bpf_testmod(bool verbose) 450 { 451 return load_module("bpf_testmod.ko", verbose); 452 } 453 454 /* 455 * Trigger synchronize_rcu() in kernel. 456 */ 457 int kern_sync_rcu(void) 458 { 459 return syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0, 0); 460 } 461 462 int uffd_block_page(void *fault_addr) 463 { 464 struct uffdio_register uffd_register = {}; 465 struct uffdio_api uffd_api = {}; 466 int uffd; 467 468 uffd = syscall(__NR_userfaultfd, O_CLOEXEC); 469 if (uffd < 0) 470 return -errno; 471 472 uffd_api.api = UFFD_API; 473 uffd_api.features = 0; 474 if (ioctl(uffd, UFFDIO_API, &uffd_api)) { 475 close(uffd); 476 return -1; 477 } 478 479 uffd_register.range.start = (unsigned long)fault_addr; 480 uffd_register.range.len = getpagesize(); 481 uffd_register.mode = UFFDIO_REGISTER_MODE_MISSING; 482 if (ioctl(uffd, UFFDIO_REGISTER, &uffd_register)) { 483 close(uffd); 484 return -1; 485 } 486 return uffd; 487 } 488 489 int get_xlated_program(int fd_prog, struct bpf_insn **buf, __u32 *cnt) 490 { 491 __u32 buf_element_size = sizeof(struct bpf_insn); 492 struct bpf_prog_info info = {}; 493 __u32 info_len = sizeof(info); 494 __u32 xlated_prog_len; 495 496 if (bpf_prog_get_info_by_fd(fd_prog, &info, &info_len)) { 497 perror("bpf_prog_get_info_by_fd failed"); 498 return -1; 499 } 500 501 xlated_prog_len = info.xlated_prog_len; 502 if (xlated_prog_len % buf_element_size) { 503 printf("Program length %u is not multiple of %u\n", 504 xlated_prog_len, buf_element_size); 505 return -1; 506 } 507 508 *cnt = xlated_prog_len / buf_element_size; 509 *buf = calloc(*cnt, buf_element_size); 510 if (!*buf) { 511 perror("can't allocate xlated program buffer"); 512 return -ENOMEM; 513 } 514 515 bzero(&info, sizeof(info)); 516 info.xlated_prog_len = xlated_prog_len; 517 info.xlated_prog_insns = (__u64)(unsigned long)*buf; 518 if (bpf_prog_get_info_by_fd(fd_prog, &info, &info_len)) { 519 perror("second bpf_prog_get_info_by_fd failed"); 520 goto out_free_buf; 521 } 522 523 return 0; 524 525 out_free_buf: 526 free(*buf); 527 *buf = NULL; 528 return -1; 529 } 530 531 bool is_jit_enabled(void) 532 { 533 const char *jit_sysctl = "/proc/sys/net/core/bpf_jit_enable"; 534 bool enabled = false; 535 int sysctl_fd; 536 537 sysctl_fd = open(jit_sysctl, O_RDONLY); 538 if (sysctl_fd != -1) { 539 char tmpc; 540 541 if (read(sysctl_fd, &tmpc, sizeof(tmpc)) == 1) 542 enabled = (tmpc != '0'); 543 close(sysctl_fd); 544 } 545 546 return enabled; 547 } 548 549 /* 550 * Whether the kernel accepts a program using more than 512 bytes of stack, 551 * which depends on the JIT in use. Probed once with a program that stores 552 * at the 2 KiB depth. Only the verifier's verdict on that store is cached: 553 * a load that fails for another reason, such as a missing capability, is 554 * reported and probed again on the next call. 555 */ 556 bool is_large_stack_supported(void) 557 { 558 static int supported = -1; 559 struct bpf_insn insns[] = { 560 BPF_ST_MEM(BPF_DW, BPF_REG_10, -2048, 0), 561 BPF_MOV64_IMM(BPF_REG_0, 0), 562 BPF_EXIT_INSN(), 563 }; 564 char log[1024] = {}; 565 LIBBPF_OPTS(bpf_prog_load_opts, opts, 566 .log_buf = log, 567 .log_size = sizeof(log), 568 .log_level = 1, 569 ); 570 int fd; 571 572 if (supported >= 0) 573 return supported; 574 575 fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, ARRAY_SIZE(insns), 576 &opts); 577 if (fd >= 0) { 578 close(fd); 579 supported = 1; 580 } else if (strstr(log, "invalid write to stack")) { 581 supported = 0; 582 } else { 583 fprintf(stderr, "%s: probe failed with errno %d, assuming 512 bytes:\n%s", 584 __func__, errno, log); 585 return false; 586 } 587 return supported; 588 } 589 590 int stack_mprotect(void) 591 { 592 void *buf; 593 long sz; 594 int ret; 595 596 sz = sysconf(_SC_PAGESIZE); 597 if (sz < 0) 598 return sz; 599 600 buf = alloca(sz * 3); 601 ret = mprotect((void *)(((unsigned long)(buf + sz)) & ~(sz - 1)), sz, 602 PROT_READ | PROT_WRITE | PROT_EXEC); 603 return ret; 604 } 605 606 int compare_text_to_expected(const char *actual, const char *expected) 607 { 608 char exp_path[] = "/tmp/selftest_expected.XXXXXX"; 609 char act_path[] = "/tmp/selftest_actual.XXXXXX"; 610 char buf[512], cmd[128]; 611 int exp_fd, act_fd; 612 FILE *p; 613 614 if (!strcmp(actual, expected)) 615 return 0; 616 617 exp_fd = mkstemp(exp_path); 618 act_fd = mkstemp(act_path); 619 if (exp_fd < 0 || act_fd < 0) { 620 fprintf(stdout, "output differs, no temp file for a diff\n"); 621 goto out; 622 } 623 624 dprintf(exp_fd, "%s", expected); 625 dprintf(act_fd, "%s", actual); 626 627 snprintf(cmd, sizeof(cmd), "diff -u '%s' '%s'", exp_path, act_path); 628 p = popen(cmd, "r"); 629 if (!p) { 630 fprintf(stdout, "output differs, '%s' did not run\n", cmd); 631 goto out; 632 } 633 while (fgets(buf, sizeof(buf), p)) 634 fputs(buf, stdout); 635 pclose(p); 636 637 out: 638 if (exp_fd >= 0) { 639 close(exp_fd); 640 unlink(exp_path); 641 } 642 if (act_fd >= 0) { 643 close(act_fd); 644 unlink(act_path); 645 } 646 return -1; 647 } 648 649 int testmod_member_has_type_tag(const char *struct_name, const char *member, const char *tag) 650 { 651 struct btf *vmlinux_btf, *module_btf = NULL; 652 const struct btf_member *m; 653 const struct btf_type *t; 654 int err = 0, id, i; 655 656 vmlinux_btf = btf__load_vmlinux_btf(); 657 if (!vmlinux_btf) 658 return -errno; 659 module_btf = btf__load_module_btf("bpf_testmod", vmlinux_btf); 660 if (!module_btf) { 661 err = -errno; 662 goto out; 663 } 664 id = btf__find_by_name_kind_own(module_btf, struct_name, BTF_KIND_STRUCT); 665 if (id < 0) { 666 err = id; 667 goto out; 668 } 669 t = btf__type_by_id(module_btf, id); 670 err = -ENOENT; 671 for (i = 0, m = btf_members(t); i < btf_vlen(t); i++, m++) { 672 if (strcmp(btf__name_by_offset(module_btf, m->name_off), member)) 673 continue; 674 err = 0; 675 /* the tag sits on the pointee, behind the pointer and other modifiers */ 676 for (id = m->type; id; id = t->type) { 677 t = btf__type_by_id(module_btf, id); 678 if (btf_is_type_tag(t) && !strcmp(btf__name_by_offset(module_btf, t->name_off), tag)) { 679 err = 1; 680 break; 681 } 682 if (!btf_is_ptr(t) && !btf_is_mod(t) && !btf_is_typedef(t)) 683 break; 684 } 685 break; 686 } 687 out: 688 btf__free(module_btf); 689 btf__free(vmlinux_btf); 690 return err; 691 } 692