~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/test_loader.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php