]> Git Repo - linux.git/blob - tools/testing/selftests/bpf/prog_tests/log_fixup.c
Linux 6.14-rc3
[linux.git] / tools / testing / selftests / bpf / prog_tests / log_fixup.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3 #include <test_progs.h>
4 #include <bpf/btf.h>
5
6 #include "test_log_fixup.skel.h"
7
8 enum trunc_type {
9         TRUNC_NONE,
10         TRUNC_PARTIAL,
11         TRUNC_FULL,
12 };
13
14 static void bad_core_relo(size_t log_buf_size, enum trunc_type trunc_type)
15 {
16         char log_buf[8 * 1024];
17         struct test_log_fixup* skel;
18         int err;
19
20         skel = test_log_fixup__open();
21         if (!ASSERT_OK_PTR(skel, "skel_open"))
22                 return;
23
24         bpf_program__set_autoload(skel->progs.bad_relo, true);
25         memset(log_buf, 0, sizeof(log_buf));
26         bpf_program__set_log_buf(skel->progs.bad_relo, log_buf, log_buf_size ?: sizeof(log_buf));
27         bpf_program__set_log_level(skel->progs.bad_relo, 1 | 8); /* BPF_LOG_FIXED to force truncation */
28
29         err = test_log_fixup__load(skel);
30         if (!ASSERT_ERR(err, "load_fail"))
31                 goto cleanup;
32
33         ASSERT_HAS_SUBSTR(log_buf,
34                           "0: <invalid CO-RE relocation>\n"
35                           "failed to resolve CO-RE relocation <byte_sz> ",
36                           "log_buf_part1");
37
38         switch (trunc_type) {
39         case TRUNC_NONE:
40                 ASSERT_HAS_SUBSTR(log_buf,
41                                   "struct task_struct___bad.fake_field (0:1 @ offset 4)\n",
42                                   "log_buf_part2");
43                 ASSERT_HAS_SUBSTR(log_buf,
44                                   "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n",
45                                   "log_buf_end");
46                 break;
47         case TRUNC_PARTIAL:
48                 /* we should get full libbpf message patch */
49                 ASSERT_HAS_SUBSTR(log_buf,
50                                   "struct task_struct___bad.fake_field (0:1 @ offset 4)\n",
51                                   "log_buf_part2");
52                 /* we shouldn't get full end of BPF verifier log */
53                 ASSERT_NULL(strstr(log_buf, "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n"),
54                             "log_buf_end");
55                 break;
56         case TRUNC_FULL:
57                 /* we shouldn't get second part of libbpf message patch */
58                 ASSERT_NULL(strstr(log_buf, "struct task_struct___bad.fake_field (0:1 @ offset 4)\n"),
59                             "log_buf_part2");
60                 /* we shouldn't get full end of BPF verifier log */
61                 ASSERT_NULL(strstr(log_buf, "max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0\n"),
62                             "log_buf_end");
63                 break;
64         }
65
66         if (env.verbosity > VERBOSE_NONE)
67                 printf("LOG:   \n=================\n%s=================\n", log_buf);
68 cleanup:
69         test_log_fixup__destroy(skel);
70 }
71
72 static void bad_core_relo_subprog(void)
73 {
74         char log_buf[8 * 1024];
75         struct test_log_fixup* skel;
76         int err;
77
78         skel = test_log_fixup__open();
79         if (!ASSERT_OK_PTR(skel, "skel_open"))
80                 return;
81
82         bpf_program__set_autoload(skel->progs.bad_relo_subprog, true);
83         bpf_program__set_log_buf(skel->progs.bad_relo_subprog, log_buf, sizeof(log_buf));
84
85         err = test_log_fixup__load(skel);
86         if (!ASSERT_ERR(err, "load_fail"))
87                 goto cleanup;
88
89         ASSERT_HAS_SUBSTR(log_buf,
90                           ": <invalid CO-RE relocation>\n"
91                           "failed to resolve CO-RE relocation <byte_off> ",
92                           "log_buf");
93         ASSERT_HAS_SUBSTR(log_buf,
94                           "struct task_struct___bad.fake_field_subprog (0:2 @ offset 8)\n",
95                           "log_buf");
96
97         if (env.verbosity > VERBOSE_NONE)
98                 printf("LOG:   \n=================\n%s=================\n", log_buf);
99
100 cleanup:
101         test_log_fixup__destroy(skel);
102 }
103
104 static void missing_map(void)
105 {
106         char log_buf[8 * 1024];
107         struct test_log_fixup* skel;
108         int err;
109
110         skel = test_log_fixup__open();
111         if (!ASSERT_OK_PTR(skel, "skel_open"))
112                 return;
113
114         bpf_map__set_autocreate(skel->maps.missing_map, false);
115
116         bpf_program__set_autoload(skel->progs.use_missing_map, true);
117         bpf_program__set_log_buf(skel->progs.use_missing_map, log_buf, sizeof(log_buf));
118
119         err = test_log_fixup__load(skel);
120         if (!ASSERT_ERR(err, "load_fail"))
121                 goto cleanup;
122
123         ASSERT_TRUE(bpf_map__autocreate(skel->maps.existing_map), "existing_map_autocreate");
124         ASSERT_FALSE(bpf_map__autocreate(skel->maps.missing_map), "missing_map_autocreate");
125
126         ASSERT_HAS_SUBSTR(log_buf,
127                           ": <invalid BPF map reference>\n"
128                           "BPF map 'missing_map' is referenced but wasn't created\n",
129                           "log_buf");
130
131         if (env.verbosity > VERBOSE_NONE)
132                 printf("LOG:   \n=================\n%s=================\n", log_buf);
133
134 cleanup:
135         test_log_fixup__destroy(skel);
136 }
137
138 static void missing_kfunc(void)
139 {
140         char log_buf[8 * 1024];
141         struct test_log_fixup* skel;
142         int err;
143
144         skel = test_log_fixup__open();
145         if (!ASSERT_OK_PTR(skel, "skel_open"))
146                 return;
147
148         bpf_program__set_autoload(skel->progs.use_missing_kfunc, true);
149         bpf_program__set_log_buf(skel->progs.use_missing_kfunc, log_buf, sizeof(log_buf));
150
151         err = test_log_fixup__load(skel);
152         if (!ASSERT_ERR(err, "load_fail"))
153                 goto cleanup;
154
155         ASSERT_HAS_SUBSTR(log_buf,
156                           "0: <invalid kfunc call>\n"
157                           "kfunc 'bpf_nonexistent_kfunc' is referenced but wasn't resolved\n",
158                           "log_buf");
159
160         if (env.verbosity > VERBOSE_NONE)
161                 printf("LOG:   \n=================\n%s=================\n", log_buf);
162
163 cleanup:
164         test_log_fixup__destroy(skel);
165 }
166
167 void test_log_fixup(void)
168 {
169         if (test__start_subtest("bad_core_relo_trunc_none"))
170                 bad_core_relo(0, TRUNC_NONE /* full buf */);
171         if (test__start_subtest("bad_core_relo_trunc_partial"))
172                 bad_core_relo(300, TRUNC_PARTIAL /* truncate original log a bit */);
173         if (test__start_subtest("bad_core_relo_trunc_full"))
174                 bad_core_relo(240, TRUNC_FULL  /* truncate also libbpf's message patch */);
175         if (test__start_subtest("bad_core_relo_subprog"))
176                 bad_core_relo_subprog();
177         if (test__start_subtest("missing_map"))
178                 missing_map();
179         if (test__start_subtest("missing_kfunc"))
180                 missing_kfunc();
181 }
This page took 0.042256 seconds and 4 git commands to generate.