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

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/prog_tests/recursive_attach.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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
  2 /* Copyright (c) 2023 Red Hat, Inc. */
  3 #include <test_progs.h>
  4 #include "fentry_recursive.skel.h"
  5 #include "fentry_recursive_target.skel.h"
  6 #include <bpf/btf.h>
  7 #include "bpf/libbpf_internal.h"
  8 
  9 /* Test recursive attachment of tracing progs with more than one nesting level
 10  * is not possible. Create a chain of attachment, verify that the last prog
 11  * will fail. Depending on the arguments, following cases are tested:
 12  *
 13  * - Recursive loading of tracing progs, without attaching (attach = false,
 14  *   detach = false). The chain looks like this:
 15  *       load target
 16  *       load fentry1 -> target
 17  *       load fentry2 -> fentry1 (fail)
 18  *
 19  * - Recursive attach of tracing progs (attach = true, detach = false). The
 20  *   chain looks like this:
 21  *       load target
 22  *       load fentry1 -> target
 23  *       attach fentry1 -> target
 24  *       load fentry2 -> fentry1 (fail)
 25  *
 26  * - Recursive attach and detach of tracing progs (attach = true, detach =
 27  *   true). This validates that attach_tracing_prog flag will be set throughout
 28  *   the whole lifecycle of an fentry prog, independently from whether it's
 29  *   detached. The chain looks like this:
 30  *       load target
 31  *       load fentry1 -> target
 32  *       attach fentry1 -> target
 33  *       detach fentry1
 34  *       load fentry2 -> fentry1 (fail)
 35  */
 36 static void test_recursive_fentry_chain(bool attach, bool detach)
 37 {
 38         struct fentry_recursive_target *target_skel = NULL;
 39         struct fentry_recursive *tracing_chain[2] = {};
 40         struct bpf_program *prog;
 41         int prev_fd, err;
 42 
 43         target_skel = fentry_recursive_target__open_and_load();
 44         if (!ASSERT_OK_PTR(target_skel, "fentry_recursive_target__open_and_load"))
 45                 return;
 46 
 47         /* Create an attachment chain with two fentry progs */
 48         for (int i = 0; i < 2; i++) {
 49                 tracing_chain[i] = fentry_recursive__open();
 50                 if (!ASSERT_OK_PTR(tracing_chain[i], "fentry_recursive__open"))
 51                         goto close_prog;
 52 
 53                 /* The first prog in the chain is going to be attached to the target
 54                  * fentry program, the second one to the previous in the chain.
 55                  */
 56                 prog = tracing_chain[i]->progs.recursive_attach;
 57                 if (i == 0) {
 58                         prev_fd = bpf_program__fd(target_skel->progs.test1);
 59                         err = bpf_program__set_attach_target(prog, prev_fd, "test1");
 60                 } else {
 61                         prev_fd = bpf_program__fd(tracing_chain[i-1]->progs.recursive_attach);
 62                         err = bpf_program__set_attach_target(prog, prev_fd, "recursive_attach");
 63                 }
 64 
 65                 if (!ASSERT_OK(err, "bpf_program__set_attach_target"))
 66                         goto close_prog;
 67 
 68                 err = fentry_recursive__load(tracing_chain[i]);
 69                 /* The first attach should succeed, the second fail */
 70                 if (i == 0) {
 71                         if (!ASSERT_OK(err, "fentry_recursive__load"))
 72                                 goto close_prog;
 73 
 74                         if (attach) {
 75                                 err = fentry_recursive__attach(tracing_chain[i]);
 76                                 if (!ASSERT_OK(err, "fentry_recursive__attach"))
 77                                         goto close_prog;
 78                         }
 79 
 80                         if (detach) {
 81                                 /* Flag attach_tracing_prog should still be set, preventing
 82                                  * attachment of the following prog.
 83                                  */
 84                                 fentry_recursive__detach(tracing_chain[i]);
 85                         }
 86                 } else {
 87                         if (!ASSERT_ERR(err, "fentry_recursive__load"))
 88                                 goto close_prog;
 89                 }
 90         }
 91 
 92 close_prog:
 93         fentry_recursive_target__destroy(target_skel);
 94         for (int i = 0; i < 2; i++) {
 95                 fentry_recursive__destroy(tracing_chain[i]);
 96         }
 97 }
 98 
 99 void test_recursive_fentry(void)
100 {
101         if (test__start_subtest("attach"))
102                 test_recursive_fentry_chain(true, false);
103         if (test__start_subtest("load"))
104                 test_recursive_fentry_chain(false, false);
105         if (test__start_subtest("detach"))
106                 test_recursive_fentry_chain(true, true);
107 }
108 
109 /* Test that a tracing prog reattachment (when we land in
110  * "prog->aux->dst_trampoline and tgt_prog is NULL" branch in
111  * bpf_tracing_prog_attach) does not lead to a crash due to missing attach_btf
112  */
113 void test_fentry_attach_btf_presence(void)
114 {
115         struct fentry_recursive_target *target_skel = NULL;
116         struct fentry_recursive *tracing_skel = NULL;
117         struct bpf_program *prog;
118         int err, link_fd, tgt_prog_fd;
119 
120         target_skel = fentry_recursive_target__open_and_load();
121         if (!ASSERT_OK_PTR(target_skel, "fentry_recursive_target__open_and_load"))
122                 goto close_prog;
123 
124         tracing_skel = fentry_recursive__open();
125         if (!ASSERT_OK_PTR(tracing_skel, "fentry_recursive__open"))
126                 goto close_prog;
127 
128         prog = tracing_skel->progs.recursive_attach;
129         tgt_prog_fd = bpf_program__fd(target_skel->progs.fentry_target);
130         err = bpf_program__set_attach_target(prog, tgt_prog_fd, "fentry_target");
131         if (!ASSERT_OK(err, "bpf_program__set_attach_target"))
132                 goto close_prog;
133 
134         err = fentry_recursive__load(tracing_skel);
135         if (!ASSERT_OK(err, "fentry_recursive__load"))
136                 goto close_prog;
137 
138         tgt_prog_fd = bpf_program__fd(tracing_skel->progs.recursive_attach);
139         link_fd = bpf_link_create(tgt_prog_fd, 0, BPF_TRACE_FENTRY, NULL);
140         if (!ASSERT_GE(link_fd, 0, "link_fd"))
141                 goto close_prog;
142 
143         fentry_recursive__detach(tracing_skel);
144 
145         err = fentry_recursive__attach(tracing_skel);
146         ASSERT_ERR(err, "fentry_recursive__attach");
147 
148 close_prog:
149         fentry_recursive_target__destroy(target_skel);
150         fentry_recursive__destroy(tracing_skel);
151 }
152 

~ [ 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