Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
0003 #include <test_progs.h>
0004 #include <bpf/btf.h>
0005 
0006 #include "test_log_fixup.skel.h"
0007 
0008 enum trunc_type {
0009     TRUNC_NONE,
0010     TRUNC_PARTIAL,
0011     TRUNC_FULL,
0012 };
0013 
0014 static void bad_core_relo(size_t log_buf_size, enum trunc_type trunc_type)
0015 {
0016     char log_buf[8 * 1024];
0017     struct test_log_fixup* skel;
0018     int err;
0019 
0020     skel = test_log_fixup__open();
0021     if (!ASSERT_OK_PTR(skel, "skel_open"))
0022         return;
0023 
0024     bpf_program__set_autoload(skel->progs.bad_relo, true);
0025     memset(log_buf, 0, sizeof(log_buf));
0026     bpf_program__set_log_buf(skel->progs.bad_relo, log_buf, log_buf_size ?: sizeof(log_buf));
0027 
0028     err = test_log_fixup__load(skel);
0029     if (!ASSERT_ERR(err, "load_fail"))
0030         goto cleanup;
0031 
0032     ASSERT_HAS_SUBSTR(log_buf,
0033               "0: <invalid CO-RE relocation>\n"
0034               "failed to resolve CO-RE relocation <byte_sz> ",
0035               "log_buf_part1");
0036 
0037     switch (trunc_type) {
0038     case TRUNC_NONE:
0039         ASSERT_HAS_SUBSTR(log_buf,
0040                   "struct task_struct___bad.fake_field (0:1 @ offset 4)\n",
0041                   "log_buf_part2");
0042         ASSERT_HAS_SUBSTR(log_buf,
0043                   "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n",
0044                   "log_buf_end");
0045         break;
0046     case TRUNC_PARTIAL:
0047         /* we should get full libbpf message patch */
0048         ASSERT_HAS_SUBSTR(log_buf,
0049                   "struct task_struct___bad.fake_field (0:1 @ offset 4)\n",
0050                   "log_buf_part2");
0051         /* we shouldn't get full end of BPF verifier log */
0052         ASSERT_NULL(strstr(log_buf, "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n"),
0053                 "log_buf_end");
0054         break;
0055     case TRUNC_FULL:
0056         /* we shouldn't get second part of libbpf message patch */
0057         ASSERT_NULL(strstr(log_buf, "struct task_struct___bad.fake_field (0:1 @ offset 4)\n"),
0058                 "log_buf_part2");
0059         /* we shouldn't get full end of BPF verifier log */
0060         ASSERT_NULL(strstr(log_buf, "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n"),
0061                 "log_buf_end");
0062         break;
0063     }
0064 
0065     if (env.verbosity > VERBOSE_NONE)
0066         printf("LOG:   \n=================\n%s=================\n", log_buf);
0067 cleanup:
0068     test_log_fixup__destroy(skel);
0069 }
0070 
0071 static void bad_core_relo_subprog(void)
0072 {
0073     char log_buf[8 * 1024];
0074     struct test_log_fixup* skel;
0075     int err;
0076 
0077     skel = test_log_fixup__open();
0078     if (!ASSERT_OK_PTR(skel, "skel_open"))
0079         return;
0080 
0081     bpf_program__set_autoload(skel->progs.bad_relo_subprog, true);
0082     bpf_program__set_log_buf(skel->progs.bad_relo_subprog, log_buf, sizeof(log_buf));
0083 
0084     err = test_log_fixup__load(skel);
0085     if (!ASSERT_ERR(err, "load_fail"))
0086         goto cleanup;
0087 
0088     ASSERT_HAS_SUBSTR(log_buf,
0089               ": <invalid CO-RE relocation>\n"
0090               "failed to resolve CO-RE relocation <byte_off> ",
0091               "log_buf");
0092     ASSERT_HAS_SUBSTR(log_buf,
0093               "struct task_struct___bad.fake_field_subprog (0:2 @ offset 8)\n",
0094               "log_buf");
0095 
0096     if (env.verbosity > VERBOSE_NONE)
0097         printf("LOG:   \n=================\n%s=================\n", log_buf);
0098 
0099 cleanup:
0100     test_log_fixup__destroy(skel);
0101 }
0102 
0103 static void missing_map(void)
0104 {
0105     char log_buf[8 * 1024];
0106     struct test_log_fixup* skel;
0107     int err;
0108 
0109     skel = test_log_fixup__open();
0110     if (!ASSERT_OK_PTR(skel, "skel_open"))
0111         return;
0112 
0113     bpf_map__set_autocreate(skel->maps.missing_map, false);
0114 
0115     bpf_program__set_autoload(skel->progs.use_missing_map, true);
0116     bpf_program__set_log_buf(skel->progs.use_missing_map, log_buf, sizeof(log_buf));
0117 
0118     err = test_log_fixup__load(skel);
0119     if (!ASSERT_ERR(err, "load_fail"))
0120         goto cleanup;
0121 
0122     ASSERT_TRUE(bpf_map__autocreate(skel->maps.existing_map), "existing_map_autocreate");
0123     ASSERT_FALSE(bpf_map__autocreate(skel->maps.missing_map), "missing_map_autocreate");
0124 
0125     ASSERT_HAS_SUBSTR(log_buf,
0126               "8: <invalid BPF map reference>\n"
0127               "BPF map 'missing_map' is referenced but wasn't created\n",
0128               "log_buf");
0129 
0130     if (env.verbosity > VERBOSE_NONE)
0131         printf("LOG:   \n=================\n%s=================\n", log_buf);
0132 
0133 cleanup:
0134     test_log_fixup__destroy(skel);
0135 }
0136 
0137 void test_log_fixup(void)
0138 {
0139     if (test__start_subtest("bad_core_relo_trunc_none"))
0140         bad_core_relo(0, TRUNC_NONE /* full buf */);
0141     if (test__start_subtest("bad_core_relo_trunc_partial"))
0142         bad_core_relo(300, TRUNC_PARTIAL /* truncate original log a bit */);
0143     if (test__start_subtest("bad_core_relo_trunc_full"))
0144         bad_core_relo(250, TRUNC_FULL  /* truncate also libbpf's message patch */);
0145     if (test__start_subtest("bad_core_relo_subprog"))
0146         bad_core_relo_subprog();
0147     if (test__start_subtest("missing_map"))
0148         missing_map();
0149 }