|
36 | 36 | #define TEST_TAG_ARCH "comment:test_arch="
|
37 | 37 | #define TEST_TAG_JITED_PFX "comment:test_jited="
|
38 | 38 | #define TEST_TAG_JITED_PFX_UNPRIV "comment:test_jited_unpriv="
|
| 39 | +#define TEST_TAG_CAPS_UNPRIV "comment:test_caps_unpriv=" |
39 | 40 |
|
40 | 41 | /* Warning: duplicated in bpf_misc.h */
|
41 | 42 | #define POINTER_VALUE 0xcafe4all
|
@@ -74,6 +75,7 @@ struct test_subspec {
|
74 | 75 | struct expected_msgs jited;
|
75 | 76 | int retval;
|
76 | 77 | bool execute;
|
| 78 | + __u64 caps; |
77 | 79 | };
|
78 | 80 |
|
79 | 81 | struct test_spec {
|
@@ -276,6 +278,37 @@ static int parse_int(const char *str, int *val, const char *name)
|
276 | 278 | return 0;
|
277 | 279 | }
|
278 | 280 |
|
| 281 | +static int parse_caps(const char *str, __u64 *val, const char *name) |
| 282 | +{ |
| 283 | + int cap_flag = 0; |
| 284 | + char *token = NULL, *saveptr = NULL; |
| 285 | + |
| 286 | + char *str_cpy = strdup(str); |
| 287 | + if (str_cpy == NULL) { |
| 288 | + PRINT_FAIL("Memory allocation failed\n"); |
| 289 | + return -EINVAL; |
| 290 | + } |
| 291 | + |
| 292 | + token = strtok_r(str_cpy, "|", &saveptr); |
| 293 | + while (token != NULL) { |
| 294 | + errno = 0; |
| 295 | + if (!strncmp("CAP_", token, sizeof("CAP_") - 1)) { |
| 296 | + PRINT_FAIL("define %s constant in bpf_misc.h, failed to parse caps\n", token); |
| 297 | + return -EINVAL; |
| 298 | + } |
| 299 | + cap_flag = strtol(token, NULL, 10); |
| 300 | + if (!cap_flag || errno) { |
| 301 | + PRINT_FAIL("failed to parse caps %s\n", name); |
| 302 | + return -EINVAL; |
| 303 | + } |
| 304 | + *val |= (1ULL << cap_flag); |
| 305 | + token = strtok_r(NULL, "|", &saveptr); |
| 306 | + } |
| 307 | + |
| 308 | + free(str_cpy); |
| 309 | + return 0; |
| 310 | +} |
| 311 | + |
279 | 312 | static int parse_retval(const char *str, int *val, const char *name)
|
280 | 313 | {
|
281 | 314 | struct {
|
@@ -541,6 +574,12 @@ static int parse_test_spec(struct test_loader *tester,
|
541 | 574 | jit_on_next_line = true;
|
542 | 575 | } else if (str_has_pfx(s, TEST_BTF_PATH)) {
|
543 | 576 | spec->btf_custom_path = s + sizeof(TEST_BTF_PATH) - 1;
|
| 577 | + } else if (str_has_pfx(s, TEST_TAG_CAPS_UNPRIV)) { |
| 578 | + val = s + sizeof(TEST_TAG_CAPS_UNPRIV) - 1; |
| 579 | + err = parse_caps(val, &spec->unpriv.caps, "test caps"); |
| 580 | + if (err) |
| 581 | + goto cleanup; |
| 582 | + spec->mode_mask |= UNPRIV; |
544 | 583 | }
|
545 | 584 | }
|
546 | 585 |
|
@@ -917,6 +956,13 @@ void run_subtest(struct test_loader *tester,
|
917 | 956 | test__end_subtest();
|
918 | 957 | return;
|
919 | 958 | }
|
| 959 | + if (subspec->caps) { |
| 960 | + err = cap_enable_effective(subspec->caps, NULL); |
| 961 | + if (err) { |
| 962 | + PRINT_FAIL("failed to set capabilities: %i, %s\n", err, strerror(err)); |
| 963 | + goto subtest_cleanup; |
| 964 | + } |
| 965 | + } |
920 | 966 | }
|
921 | 967 |
|
922 | 968 | /* Implicitly reset to NULL if next test case doesn't specify */
|
|
0 commit comments