projects/linux·blob master · refs

194 lines · 4.9 KiB

1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2020 Facebook */
3
4#include <test_progs.h>
5#include <stdbool.h>
6#include "test_module_attach.skel.h"
7#include "testing_helpers.h"
8
9static const char * const read_tests[] = {
10 "handle_raw_tp",
11 "handle_tp_btf",
12 "handle_fentry",
13 "handle_fentry_explicit",
14 "handle_fmod_ret",
15};
16
17static const char * const detach_tests[] = {
18 "handle_fentry",
19 "handle_fexit",
20 "kprobe_multi",
21};
22
23static const int READ_SZ = 456;
24static const int WRITE_SZ = 457;
25
26static int trigger_module_test_writable(int *val)
27{
28 int fd, err;
29 char buf[65];
30 ssize_t rd;
31
32 fd = open(BPF_TESTMOD_TEST_FILE, O_RDONLY);
33 err = -errno;
34 if (!ASSERT_GE(fd, 0, "testmode_file_open"))
35 return err;
36
37 rd = read(fd, buf, sizeof(buf) - 1);
38 err = -errno;
39 if (!ASSERT_GT(rd, 0, "testmod_file_rd_val")) {
40 close(fd);
41 return err;
42 }
43
44 buf[rd] = '\0';
45 *val = strtol(buf, NULL, 0);
46 close(fd);
47
48 return 0;
49}
50
51static void test_module_attach_prog(const char *prog_name, int sz,
52 const char *attach_target, int ret)
53{
54 struct test_module_attach *skel;
55 struct bpf_program *prog;
56 int err;
57
58 skel = test_module_attach__open();
59 if (!ASSERT_OK_PTR(skel, "module_attach open"))
60 return;
61
62 prog = bpf_object__find_program_by_name(skel->obj, prog_name);
63 if (!ASSERT_OK_PTR(prog, "module_attach find_program"))
64 goto cleanup;
65 bpf_program__set_autoload(prog, true);
66
67 if (attach_target) {
68 err = bpf_program__set_attach_target(prog, 0, attach_target);
69 if (!ASSERT_OK(err, attach_target))
70 goto cleanup;
71 }
72
73 err = test_module_attach__load(skel);
74 if (!ASSERT_OK(err, "module_attach load"))
75 goto cleanup;
76
77 err = test_module_attach__attach(skel);
78 if (!ASSERT_OK(err, "module_attach attach"))
79 goto cleanup;
80
81 if (sz) {
82 /* trigger both read and write though each test uses only one */
83 ASSERT_OK(trigger_module_test_read(sz), "trigger_read");
84 ASSERT_OK(trigger_module_test_write(sz), "trigger_write");
85
86 ASSERT_EQ(skel->bss->sz, sz, prog_name);
87 }
88
89 if (ret)
90 ASSERT_EQ(skel->bss->retval, ret, "ret");
91cleanup:
92 test_module_attach__destroy(skel);
93}
94
95static void test_module_attach_writable(void)
96{
97 struct test_module_attach__bss *bss;
98 struct test_module_attach *skel;
99 int writable_val = 0;
100 int err;
101
102 skel = test_module_attach__open();
103 if (!ASSERT_OK_PTR(skel, "module_attach open"))
104 return;
105
106 bpf_program__set_autoload(skel->progs.handle_raw_tp_writable_bare, true);
107
108 err = test_module_attach__load(skel);
109 if (!ASSERT_OK(err, "module_attach load"))
110 goto cleanup;
111
112 bss = skel->bss;
113
114 err = test_module_attach__attach(skel);
115 if (!ASSERT_OK(err, "module_attach attach"))
116 goto cleanup;
117
118 bss->raw_tp_writable_bare_early_ret = true;
119 bss->raw_tp_writable_bare_out_val = 0xf1f2f3f4;
120 ASSERT_OK(trigger_module_test_writable(&writable_val),
121 "trigger_writable");
122 ASSERT_EQ(bss->raw_tp_writable_bare_in_val, 1024, "writable_test_in");
123 ASSERT_EQ(bss->raw_tp_writable_bare_out_val, writable_val,
124 "writable_test_out");
125cleanup:
126 test_module_attach__destroy(skel);
127}
128
129static void test_module_attach_detach(const char *prog_name)
130{
131 struct test_module_attach *skel;
132 struct bpf_program *prog;
133 struct bpf_link *link;
134 int err;
135
136 skel = test_module_attach__open();
137 if (!ASSERT_OK_PTR(skel, "module_attach open"))
138 return;
139
140 prog = bpf_object__find_program_by_name(skel->obj, prog_name);
141 if (!ASSERT_OK_PTR(prog, "module_attach find_program"))
142 goto cleanup;
143 bpf_program__set_autoload(prog, true);
144
145 err = test_module_attach__load(skel);
146 if (!ASSERT_OK(err, "module_attach load"))
147 goto cleanup;
148
149 /* attach and make sure it gets module reference */
150 link = bpf_program__attach(prog);
151 if (!ASSERT_OK_PTR(link, "module_attach attach"))
152 goto cleanup;
153
154 ASSERT_ERR(try_unload_module("bpf_testmod", 1, false), "try_unload_module");
155 bpf_link__destroy(link);
156cleanup:
157 test_module_attach__destroy(skel);
158}
159
160void test_module_attach(void)
161{
162 int i;
163
164 for (i = 0; i < ARRAY_SIZE(read_tests); i++) {
165 if (!test__start_subtest(read_tests[i]))
166 continue;
167 test_module_attach_prog(read_tests[i], READ_SZ, NULL, 0);
168 }
169 if (test__start_subtest("handle_raw_tp_bare"))
170 test_module_attach_prog("handle_raw_tp_bare", WRITE_SZ, NULL, 0);
171 if (test__start_subtest("handle_raw_tp_writable_bare"))
172 test_module_attach_writable();
173 if (test__start_subtest("handle_fentry_manual")) {
174 test_module_attach_prog("handle_fentry_manual", READ_SZ,
175 "bpf_testmod_test_read", 0);
176 }
177 if (test__start_subtest("handle_fentry_explicit_manual")) {
178 test_module_attach_prog("handle_fentry_explicit_manual",
179 READ_SZ,
180 "bpf_testmod:bpf_testmod_test_read", 0);
181 }
182 if (test__start_subtest("handle_fexit"))
183 test_module_attach_prog("handle_fexit", READ_SZ, NULL, -EIO);
184 if (test__start_subtest("handle_fexit_ret"))
185 test_module_attach_prog("handle_fexit_ret", 0, NULL, 0);
186 for (i = 0; i < ARRAY_SIZE(detach_tests); i++) {
187 char test_name[50];
188
189 snprintf(test_name, sizeof(test_name), "%s_detach", detach_tests[i]);
190 if (!test__start_subtest(test_name))
191 continue;
192 test_module_attach_detach(detach_tests[i]);
193 }
194}