]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/prog_tests/exceptions.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / prog_tests / exceptions.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <test_progs.h>
3 #include <network_helpers.h>
4
5 #include "exceptions.skel.h"
6 #include "exceptions_ext.skel.h"
7 #include "exceptions_fail.skel.h"
8 #include "exceptions_assert.skel.h"
9
10 static char log_buf[1024 * 1024];
11
12 static void test_exceptions_failure(void)
13 {
14         RUN_TESTS(exceptions_fail);
15 }
16
17 static void test_exceptions_success(void)
18 {
19         LIBBPF_OPTS(bpf_test_run_opts, ropts,
20                 .data_in = &pkt_v4,
21                 .data_size_in = sizeof(pkt_v4),
22                 .repeat = 1,
23         );
24         struct exceptions_ext *eskel = NULL;
25         struct exceptions *skel;
26         int ret;
27
28         skel = exceptions__open();
29         if (!ASSERT_OK_PTR(skel, "exceptions__open"))
30                 return;
31
32         ret = exceptions__load(skel);
33         if (!ASSERT_OK(ret, "exceptions__load"))
34                 goto done;
35
36         if (!ASSERT_OK(bpf_map_update_elem(bpf_map__fd(skel->maps.jmp_table), &(int){0},
37                                            &(int){bpf_program__fd(skel->progs.exception_tail_call_target)}, BPF_ANY),
38                        "bpf_map_update_elem jmp_table"))
39                 goto done;
40
41 #define RUN_SUCCESS(_prog, return_val)                                            \
42         if (!test__start_subtest(#_prog)) goto _prog##_##return_val;              \
43         ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs._prog), &ropts); \
44         ASSERT_OK(ret, #_prog " prog run ret");                                   \
45         ASSERT_EQ(ropts.retval, return_val, #_prog " prog run retval");           \
46         _prog##_##return_val:
47
48         RUN_SUCCESS(exception_throw_always_1, 64);
49         RUN_SUCCESS(exception_throw_always_2, 32);
50         RUN_SUCCESS(exception_throw_unwind_1, 16);
51         RUN_SUCCESS(exception_throw_unwind_2, 32);
52         RUN_SUCCESS(exception_throw_default, 0);
53         RUN_SUCCESS(exception_throw_default_value, 5);
54         RUN_SUCCESS(exception_tail_call, 24);
55         RUN_SUCCESS(exception_ext, 0);
56         RUN_SUCCESS(exception_ext_mod_cb_runtime, 35);
57         RUN_SUCCESS(exception_throw_subprog, 1);
58         RUN_SUCCESS(exception_assert_nz_gfunc, 1);
59         RUN_SUCCESS(exception_assert_zero_gfunc, 1);
60         RUN_SUCCESS(exception_assert_neg_gfunc, 1);
61         RUN_SUCCESS(exception_assert_pos_gfunc, 1);
62         RUN_SUCCESS(exception_assert_negeq_gfunc, 1);
63         RUN_SUCCESS(exception_assert_poseq_gfunc, 1);
64         RUN_SUCCESS(exception_assert_nz_gfunc_with, 1);
65         RUN_SUCCESS(exception_assert_zero_gfunc_with, 1);
66         RUN_SUCCESS(exception_assert_neg_gfunc_with, 1);
67         RUN_SUCCESS(exception_assert_pos_gfunc_with, 1);
68         RUN_SUCCESS(exception_assert_negeq_gfunc_with, 1);
69         RUN_SUCCESS(exception_assert_poseq_gfunc_with, 1);
70         RUN_SUCCESS(exception_bad_assert_nz_gfunc, 0);
71         RUN_SUCCESS(exception_bad_assert_zero_gfunc, 0);
72         RUN_SUCCESS(exception_bad_assert_neg_gfunc, 0);
73         RUN_SUCCESS(exception_bad_assert_pos_gfunc, 0);
74         RUN_SUCCESS(exception_bad_assert_negeq_gfunc, 0);
75         RUN_SUCCESS(exception_bad_assert_poseq_gfunc, 0);
76         RUN_SUCCESS(exception_bad_assert_nz_gfunc_with, 100);
77         RUN_SUCCESS(exception_bad_assert_zero_gfunc_with, 105);
78         RUN_SUCCESS(exception_bad_assert_neg_gfunc_with, 200);
79         RUN_SUCCESS(exception_bad_assert_pos_gfunc_with, 0);
80         RUN_SUCCESS(exception_bad_assert_negeq_gfunc_with, 101);
81         RUN_SUCCESS(exception_bad_assert_poseq_gfunc_with, 99);
82         RUN_SUCCESS(exception_assert_range, 1);
83         RUN_SUCCESS(exception_assert_range_with, 1);
84         RUN_SUCCESS(exception_bad_assert_range, 0);
85         RUN_SUCCESS(exception_bad_assert_range_with, 10);
86
87 #define RUN_EXT(load_ret, attach_err, expr, msg, after_link)                      \
88         {                                                                         \
89                 LIBBPF_OPTS(bpf_object_open_opts, o, .kernel_log_buf = log_buf,          \
90                                                      .kernel_log_size = sizeof(log_buf), \
91                                                      .kernel_log_level = 2);             \
92                 exceptions_ext__destroy(eskel);                                   \
93                 eskel = exceptions_ext__open_opts(&o);                            \
94                 struct bpf_program *prog = NULL;                                  \
95                 struct bpf_link *link = NULL;                                     \
96                 if (!ASSERT_OK_PTR(eskel, "exceptions_ext__open"))                \
97                         goto done;                                                \
98                 (expr);                                                           \
99                 ASSERT_OK_PTR(bpf_program__name(prog), bpf_program__name(prog));  \
100                 if (!ASSERT_EQ(exceptions_ext__load(eskel), load_ret,             \
101                                "exceptions_ext__load")) {                         \
102                         printf("%s\n", log_buf);                                  \
103                         goto done;                                                \
104                 }                                                                 \
105                 if (load_ret != 0) {                                              \
106                         if (!ASSERT_OK_PTR(strstr(log_buf, msg), "strstr")) {     \
107                                 printf("%s\n", log_buf);                          \
108                                 goto done;                                        \
109                         }                                                         \
110                 }                                                                 \
111                 if (!load_ret && attach_err) {                                    \
112                         if (!ASSERT_ERR_PTR(link = bpf_program__attach(prog), "attach err")) \
113                                 goto done;                                        \
114                 } else if (!load_ret) {                                           \
115                         if (!ASSERT_OK_PTR(link = bpf_program__attach(prog), "attach ok"))  \
116                                 goto done;                                        \
117                         (void)(after_link);                                       \
118                         bpf_link__destroy(link);                                  \
119                 }                                                                 \
120         }
121
122         if (test__start_subtest("non-throwing fentry -> exception_cb"))
123                 RUN_EXT(-EINVAL, true, ({
124                         prog = eskel->progs.pfentry;
125                         bpf_program__set_autoload(prog, true);
126                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
127                                        bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),
128                                        "exception_cb_mod"), "set_attach_target"))
129                                 goto done;
130                 }), "FENTRY/FEXIT programs cannot attach to exception callback", 0);
131
132         if (test__start_subtest("throwing fentry -> exception_cb"))
133                 RUN_EXT(-EINVAL, true, ({
134                         prog = eskel->progs.throwing_fentry;
135                         bpf_program__set_autoload(prog, true);
136                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
137                                        bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),
138                                        "exception_cb_mod"), "set_attach_target"))
139                                 goto done;
140                 }), "FENTRY/FEXIT programs cannot attach to exception callback", 0);
141
142         if (test__start_subtest("non-throwing fexit -> exception_cb"))
143                 RUN_EXT(-EINVAL, true, ({
144                         prog = eskel->progs.pfexit;
145                         bpf_program__set_autoload(prog, true);
146                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
147                                        bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),
148                                        "exception_cb_mod"), "set_attach_target"))
149                                 goto done;
150                 }), "FENTRY/FEXIT programs cannot attach to exception callback", 0);
151
152         if (test__start_subtest("throwing fexit -> exception_cb"))
153                 RUN_EXT(-EINVAL, true, ({
154                         prog = eskel->progs.throwing_fexit;
155                         bpf_program__set_autoload(prog, true);
156                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
157                                        bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),
158                                        "exception_cb_mod"), "set_attach_target"))
159                                 goto done;
160                 }), "FENTRY/FEXIT programs cannot attach to exception callback", 0);
161
162         if (test__start_subtest("throwing extension (with custom cb) -> exception_cb"))
163                 RUN_EXT(-EINVAL, true, ({
164                         prog = eskel->progs.throwing_exception_cb_extension;
165                         bpf_program__set_autoload(prog, true);
166                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
167                                        bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),
168                                        "exception_cb_mod"), "set_attach_target"))
169                                 goto done;
170                 }), "Extension programs cannot attach to exception callback", 0);
171
172         if (test__start_subtest("throwing extension -> global func in exception_cb"))
173                 RUN_EXT(0, false, ({
174                         prog = eskel->progs.throwing_exception_cb_extension;
175                         bpf_program__set_autoload(prog, true);
176                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
177                                        bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),
178                                        "exception_cb_mod_global"), "set_attach_target"))
179                                 goto done;
180                 }), "", ({ RUN_SUCCESS(exception_ext_mod_cb_runtime, 131); }));
181
182         if (test__start_subtest("throwing extension (with custom cb) -> global func in exception_cb"))
183                 RUN_EXT(0, false, ({
184                         prog = eskel->progs.throwing_extension;
185                         bpf_program__set_autoload(prog, true);
186                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
187                                        bpf_program__fd(skel->progs.exception_ext),
188                                        "exception_ext_global"), "set_attach_target"))
189                                 goto done;
190                 }), "", ({ RUN_SUCCESS(exception_ext, 128); }));
191
192         if (test__start_subtest("non-throwing fentry -> non-throwing subprog"))
193                 /* non-throwing fentry -> non-throwing subprog : OK */
194                 RUN_EXT(0, false, ({
195                         prog = eskel->progs.pfentry;
196                         bpf_program__set_autoload(prog, true);
197                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
198                                        bpf_program__fd(skel->progs.exception_throw_subprog),
199                                        "subprog"), "set_attach_target"))
200                                 goto done;
201                 }), "", 0);
202
203         if (test__start_subtest("throwing fentry -> non-throwing subprog"))
204                 /* throwing fentry -> non-throwing subprog : OK */
205                 RUN_EXT(0, false, ({
206                         prog = eskel->progs.throwing_fentry;
207                         bpf_program__set_autoload(prog, true);
208                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
209                                        bpf_program__fd(skel->progs.exception_throw_subprog),
210                                        "subprog"), "set_attach_target"))
211                                 goto done;
212                 }), "", 0);
213
214         if (test__start_subtest("non-throwing fentry -> throwing subprog"))
215                 /* non-throwing fentry -> throwing subprog : OK */
216                 RUN_EXT(0, false, ({
217                         prog = eskel->progs.pfentry;
218                         bpf_program__set_autoload(prog, true);
219                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
220                                        bpf_program__fd(skel->progs.exception_throw_subprog),
221                                        "throwing_subprog"), "set_attach_target"))
222                                 goto done;
223                 }), "", 0);
224
225         if (test__start_subtest("throwing fentry -> throwing subprog"))
226                 /* throwing fentry -> throwing subprog : OK */
227                 RUN_EXT(0, false, ({
228                         prog = eskel->progs.throwing_fentry;
229                         bpf_program__set_autoload(prog, true);
230                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
231                                        bpf_program__fd(skel->progs.exception_throw_subprog),
232                                        "throwing_subprog"), "set_attach_target"))
233                                 goto done;
234                 }), "", 0);
235
236         if (test__start_subtest("non-throwing fexit -> non-throwing subprog"))
237                 /* non-throwing fexit -> non-throwing subprog : OK */
238                 RUN_EXT(0, false, ({
239                         prog = eskel->progs.pfexit;
240                         bpf_program__set_autoload(prog, true);
241                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
242                                        bpf_program__fd(skel->progs.exception_throw_subprog),
243                                        "subprog"), "set_attach_target"))
244                                 goto done;
245                 }), "", 0);
246
247         if (test__start_subtest("throwing fexit -> non-throwing subprog"))
248                 /* throwing fexit -> non-throwing subprog : OK */
249                 RUN_EXT(0, false, ({
250                         prog = eskel->progs.throwing_fexit;
251                         bpf_program__set_autoload(prog, true);
252                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
253                                        bpf_program__fd(skel->progs.exception_throw_subprog),
254                                        "subprog"), "set_attach_target"))
255                                 goto done;
256                 }), "", 0);
257
258         if (test__start_subtest("non-throwing fexit -> throwing subprog"))
259                 /* non-throwing fexit -> throwing subprog : OK */
260                 RUN_EXT(0, false, ({
261                         prog = eskel->progs.pfexit;
262                         bpf_program__set_autoload(prog, true);
263                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
264                                        bpf_program__fd(skel->progs.exception_throw_subprog),
265                                        "throwing_subprog"), "set_attach_target"))
266                                 goto done;
267                 }), "", 0);
268
269         if (test__start_subtest("throwing fexit -> throwing subprog"))
270                 /* throwing fexit -> throwing subprog : OK */
271                 RUN_EXT(0, false, ({
272                         prog = eskel->progs.throwing_fexit;
273                         bpf_program__set_autoload(prog, true);
274                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
275                                        bpf_program__fd(skel->progs.exception_throw_subprog),
276                                        "throwing_subprog"), "set_attach_target"))
277                                 goto done;
278                 }), "", 0);
279
280         /* fmod_ret not allowed for subprog - Check so we remember to handle its
281          * throwing specification compatibility with target when supported.
282          */
283         if (test__start_subtest("non-throwing fmod_ret -> non-throwing subprog"))
284                 RUN_EXT(-EINVAL, true, ({
285                         prog = eskel->progs.pfmod_ret;
286                         bpf_program__set_autoload(prog, true);
287                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
288                                        bpf_program__fd(skel->progs.exception_throw_subprog),
289                                        "subprog"), "set_attach_target"))
290                                 goto done;
291                 }), "can't modify return codes of BPF program", 0);
292
293         /* fmod_ret not allowed for subprog - Check so we remember to handle its
294          * throwing specification compatibility with target when supported.
295          */
296         if (test__start_subtest("non-throwing fmod_ret -> non-throwing global subprog"))
297                 RUN_EXT(-EINVAL, true, ({
298                         prog = eskel->progs.pfmod_ret;
299                         bpf_program__set_autoload(prog, true);
300                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
301                                        bpf_program__fd(skel->progs.exception_throw_subprog),
302                                        "global_subprog"), "set_attach_target"))
303                                 goto done;
304                 }), "can't modify return codes of BPF program", 0);
305
306         if (test__start_subtest("non-throwing extension -> non-throwing subprog"))
307                 /* non-throwing extension -> non-throwing subprog : BAD (!global) */
308                 RUN_EXT(-EINVAL, true, ({
309                         prog = eskel->progs.extension;
310                         bpf_program__set_autoload(prog, true);
311                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
312                                        bpf_program__fd(skel->progs.exception_throw_subprog),
313                                        "subprog"), "set_attach_target"))
314                                 goto done;
315                 }), "subprog() is not a global function", 0);
316
317         if (test__start_subtest("non-throwing extension -> throwing subprog"))
318                 /* non-throwing extension -> throwing subprog : BAD (!global) */
319                 RUN_EXT(-EINVAL, true, ({
320                         prog = eskel->progs.extension;
321                         bpf_program__set_autoload(prog, true);
322                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
323                                        bpf_program__fd(skel->progs.exception_throw_subprog),
324                                        "throwing_subprog"), "set_attach_target"))
325                                 goto done;
326                 }), "throwing_subprog() is not a global function", 0);
327
328         if (test__start_subtest("non-throwing extension -> non-throwing subprog"))
329                 /* non-throwing extension -> non-throwing global subprog : OK */
330                 RUN_EXT(0, false, ({
331                         prog = eskel->progs.extension;
332                         bpf_program__set_autoload(prog, true);
333                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
334                                        bpf_program__fd(skel->progs.exception_throw_subprog),
335                                        "global_subprog"), "set_attach_target"))
336                                 goto done;
337                 }), "", 0);
338
339         if (test__start_subtest("non-throwing extension -> throwing global subprog"))
340                 /* non-throwing extension -> throwing global subprog : OK */
341                 RUN_EXT(0, false, ({
342                         prog = eskel->progs.extension;
343                         bpf_program__set_autoload(prog, true);
344                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
345                                        bpf_program__fd(skel->progs.exception_throw_subprog),
346                                        "throwing_global_subprog"), "set_attach_target"))
347                                 goto done;
348                 }), "", 0);
349
350         if (test__start_subtest("throwing extension -> throwing global subprog"))
351                 /* throwing extension -> throwing global subprog : OK */
352                 RUN_EXT(0, false, ({
353                         prog = eskel->progs.throwing_extension;
354                         bpf_program__set_autoload(prog, true);
355                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
356                                        bpf_program__fd(skel->progs.exception_throw_subprog),
357                                        "throwing_global_subprog"), "set_attach_target"))
358                                 goto done;
359                 }), "", 0);
360
361         if (test__start_subtest("throwing extension -> non-throwing global subprog"))
362                 /* throwing extension -> non-throwing global subprog : OK */
363                 RUN_EXT(0, false, ({
364                         prog = eskel->progs.throwing_extension;
365                         bpf_program__set_autoload(prog, true);
366                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
367                                        bpf_program__fd(skel->progs.exception_throw_subprog),
368                                        "global_subprog"), "set_attach_target"))
369                                 goto done;
370                 }), "", 0);
371
372         if (test__start_subtest("non-throwing extension -> main subprog"))
373                 /* non-throwing extension -> main subprog : OK */
374                 RUN_EXT(0, false, ({
375                         prog = eskel->progs.extension;
376                         bpf_program__set_autoload(prog, true);
377                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
378                                        bpf_program__fd(skel->progs.exception_throw_subprog),
379                                        "exception_throw_subprog"), "set_attach_target"))
380                                 goto done;
381                 }), "", 0);
382
383         if (test__start_subtest("throwing extension -> main subprog"))
384                 /* throwing extension -> main subprog : OK */
385                 RUN_EXT(0, false, ({
386                         prog = eskel->progs.throwing_extension;
387                         bpf_program__set_autoload(prog, true);
388                         if (!ASSERT_OK(bpf_program__set_attach_target(prog,
389                                        bpf_program__fd(skel->progs.exception_throw_subprog),
390                                        "exception_throw_subprog"), "set_attach_target"))
391                                 goto done;
392                 }), "", 0);
393
394 done:
395         exceptions_ext__destroy(eskel);
396         exceptions__destroy(skel);
397 }
398
399 static void test_exceptions_assertions(void)
400 {
401         RUN_TESTS(exceptions_assert);
402 }
403
404 void test_exceptions(void)
405 {
406         test_exceptions_success();
407         test_exceptions_failure();
408         test_exceptions_assertions();
409 }
This page took 0.052409 seconds and 4 git commands to generate.