]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - tools/testing/selftests/bpf/prog_tests/attach_probe.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[mirror_ubuntu-jammy-kernel.git] / tools / testing / selftests / bpf / prog_tests / attach_probe.c
CommitLineData
1e8611bb
AN
1// SPDX-License-Identifier: GPL-2.0
2#include <test_progs.h>
3
928ca75e
AN
4#define EMBED_FILE(NAME, PATH) \
5asm ( \
6" .pushsection \".rodata\", \"a\", @progbits \n" \
7" .global "#NAME"_data \n" \
8#NAME"_data: \n" \
9" .incbin \"" PATH "\" \n" \
10#NAME"_data_end: \n" \
11" .global "#NAME"_size \n" \
12" .type "#NAME"_size, @object \n" \
13" .size "#NAME"_size, 4 \n" \
14" .align 4, \n" \
15#NAME"_size: \n" \
16" .int "#NAME"_data_end - "#NAME"_data \n" \
17" .popsection \n" \
18); \
19extern char NAME##_data[]; \
20extern int NAME##_size;
21
1e8611bb
AN
22ssize_t get_base_addr() {
23 size_t start;
24 char buf[256];
25 FILE *f;
26
27 f = fopen("/proc/self/maps", "r");
28 if (!f)
29 return -errno;
30
31 while (fscanf(f, "%zx-%*x %s %*s\n", &start, buf) == 2) {
32 if (strcmp(buf, "r-xp") == 0) {
33 fclose(f);
34 return start;
35 }
36 }
37
38 fclose(f);
39 return -EINVAL;
40}
41
928ca75e
AN
42EMBED_FILE(probe, "test_attach_probe.o");
43
1e8611bb
AN
44void test_attach_probe(void)
45{
46 const char *kprobe_name = "kprobe/sys_nanosleep";
47 const char *kretprobe_name = "kretprobe/sys_nanosleep";
48 const char *uprobe_name = "uprobe/trigger_func";
49 const char *uretprobe_name = "uretprobe/trigger_func";
50 const int kprobe_idx = 0, kretprobe_idx = 1;
51 const int uprobe_idx = 2, uretprobe_idx = 3;
928ca75e 52 const char *obj_name = "attach_probe";
e00aca65 53 DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts,
928ca75e
AN
54 .object_name = obj_name,
55 .relaxed_maps = true,
56 );
1e8611bb
AN
57 struct bpf_program *kprobe_prog, *kretprobe_prog;
58 struct bpf_program *uprobe_prog, *uretprobe_prog;
59 struct bpf_object *obj;
928ca75e 60 int err, duration = 0, res;
1e8611bb
AN
61 struct bpf_link *kprobe_link = NULL;
62 struct bpf_link *kretprobe_link = NULL;
63 struct bpf_link *uprobe_link = NULL;
64 struct bpf_link *uretprobe_link = NULL;
65 int results_map_fd;
66 size_t uprobe_offset;
67 ssize_t base_addr;
68
69 base_addr = get_base_addr();
70 if (CHECK(base_addr < 0, "get_base_addr",
71 "failed to find base addr: %zd", base_addr))
72 return;
73 uprobe_offset = (size_t)&get_base_addr - base_addr;
74
928ca75e
AN
75 /* open object */
76 obj = bpf_object__open_mem(probe_data, probe_size, &open_opts);
77 if (CHECK(IS_ERR(obj), "obj_open_mem", "err %ld\n", PTR_ERR(obj)))
1e8611bb
AN
78 return;
79
928ca75e
AN
80 if (CHECK(strcmp(bpf_object__name(obj), obj_name), "obj_name",
81 "wrong obj name '%s', expected '%s'\n",
82 bpf_object__name(obj), obj_name))
83 goto cleanup;
84
1e8611bb
AN
85 kprobe_prog = bpf_object__find_program_by_title(obj, kprobe_name);
86 if (CHECK(!kprobe_prog, "find_probe",
87 "prog '%s' not found\n", kprobe_name))
88 goto cleanup;
89 kretprobe_prog = bpf_object__find_program_by_title(obj, kretprobe_name);
90 if (CHECK(!kretprobe_prog, "find_probe",
91 "prog '%s' not found\n", kretprobe_name))
92 goto cleanup;
93 uprobe_prog = bpf_object__find_program_by_title(obj, uprobe_name);
94 if (CHECK(!uprobe_prog, "find_probe",
95 "prog '%s' not found\n", uprobe_name))
96 goto cleanup;
97 uretprobe_prog = bpf_object__find_program_by_title(obj, uretprobe_name);
98 if (CHECK(!uretprobe_prog, "find_probe",
99 "prog '%s' not found\n", uretprobe_name))
100 goto cleanup;
101
928ca75e
AN
102 /* create maps && load programs */
103 err = bpf_object__load(obj);
104 if (CHECK(err, "obj_load", "err %d\n", err))
105 goto cleanup;
106
1e8611bb
AN
107 /* load maps */
108 results_map_fd = bpf_find_map(__func__, obj, "results_map");
109 if (CHECK(results_map_fd < 0, "find_results_map",
110 "err %d\n", results_map_fd))
111 goto cleanup;
112
113 kprobe_link = bpf_program__attach_kprobe(kprobe_prog,
114 false /* retprobe */,
1cb59a60 115 SYS_NANOSLEEP_KPROBE_NAME);
1e8611bb
AN
116 if (CHECK(IS_ERR(kprobe_link), "attach_kprobe",
117 "err %ld\n", PTR_ERR(kprobe_link))) {
118 kprobe_link = NULL;
119 goto cleanup;
120 }
121 kretprobe_link = bpf_program__attach_kprobe(kretprobe_prog,
122 true /* retprobe */,
1cb59a60 123 SYS_NANOSLEEP_KPROBE_NAME);
1e8611bb
AN
124 if (CHECK(IS_ERR(kretprobe_link), "attach_kretprobe",
125 "err %ld\n", PTR_ERR(kretprobe_link))) {
126 kretprobe_link = NULL;
127 goto cleanup;
128 }
129 uprobe_link = bpf_program__attach_uprobe(uprobe_prog,
130 false /* retprobe */,
131 0 /* self pid */,
132 "/proc/self/exe",
133 uprobe_offset);
134 if (CHECK(IS_ERR(uprobe_link), "attach_uprobe",
135 "err %ld\n", PTR_ERR(uprobe_link))) {
136 uprobe_link = NULL;
137 goto cleanup;
138 }
139 uretprobe_link = bpf_program__attach_uprobe(uretprobe_prog,
140 true /* retprobe */,
141 -1 /* any pid */,
142 "/proc/self/exe",
143 uprobe_offset);
144 if (CHECK(IS_ERR(uretprobe_link), "attach_uretprobe",
145 "err %ld\n", PTR_ERR(uretprobe_link))) {
146 uretprobe_link = NULL;
147 goto cleanup;
148 }
149
150 /* trigger & validate kprobe && kretprobe */
151 usleep(1);
152
153 err = bpf_map_lookup_elem(results_map_fd, &kprobe_idx, &res);
154 if (CHECK(err, "get_kprobe_res",
155 "failed to get kprobe res: %d\n", err))
156 goto cleanup;
157 if (CHECK(res != kprobe_idx + 1, "check_kprobe_res",
158 "wrong kprobe res: %d\n", res))
159 goto cleanup;
160
161 err = bpf_map_lookup_elem(results_map_fd, &kretprobe_idx, &res);
162 if (CHECK(err, "get_kretprobe_res",
163 "failed to get kretprobe res: %d\n", err))
164 goto cleanup;
165 if (CHECK(res != kretprobe_idx + 1, "check_kretprobe_res",
166 "wrong kretprobe res: %d\n", res))
167 goto cleanup;
168
169 /* trigger & validate uprobe & uretprobe */
170 get_base_addr();
171
172 err = bpf_map_lookup_elem(results_map_fd, &uprobe_idx, &res);
173 if (CHECK(err, "get_uprobe_res",
174 "failed to get uprobe res: %d\n", err))
175 goto cleanup;
176 if (CHECK(res != uprobe_idx + 1, "check_uprobe_res",
177 "wrong uprobe res: %d\n", res))
178 goto cleanup;
179
180 err = bpf_map_lookup_elem(results_map_fd, &uretprobe_idx, &res);
181 if (CHECK(err, "get_uretprobe_res",
182 "failed to get uretprobe res: %d\n", err))
183 goto cleanup;
184 if (CHECK(res != uretprobe_idx + 1, "check_uretprobe_res",
185 "wrong uretprobe res: %d\n", res))
186 goto cleanup;
187
188cleanup:
189 bpf_link__destroy(kprobe_link);
190 bpf_link__destroy(kretprobe_link);
191 bpf_link__destroy(uprobe_link);
192 bpf_link__destroy(uretprobe_link);
193 bpf_object__close(obj);
194}