Skip to content

Commit d571efa

Browse files
olsajiriAlexei Starovoitov
authored andcommitted
selftests/bpf: Add uprobe_multi pid filter tests
Running api and link tests also with pid filter and checking the probe gets executed only for specific pid. Spawning extra process to trigger attached uprobes and checking we get correct counts from executed programs. Signed-off-by: Jiri Olsa <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent e7cf9a4 commit d571efa

File tree

2 files changed

+126
-12
lines changed

2 files changed

+126
-12
lines changed

tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c

Lines changed: 121 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,87 @@ noinline void uprobe_multi_func_3(void)
2525
asm volatile ("");
2626
}
2727

28-
static void uprobe_multi_test_run(struct uprobe_multi *skel)
28+
struct child {
29+
int go[2];
30+
int pid;
31+
};
32+
33+
static void release_child(struct child *child)
34+
{
35+
int child_status;
36+
37+
if (!child)
38+
return;
39+
close(child->go[1]);
40+
close(child->go[0]);
41+
if (child->pid > 0)
42+
waitpid(child->pid, &child_status, 0);
43+
}
44+
45+
static void kick_child(struct child *child)
46+
{
47+
char c = 1;
48+
49+
if (child) {
50+
write(child->go[1], &c, 1);
51+
release_child(child);
52+
}
53+
fflush(NULL);
54+
}
55+
56+
static struct child *spawn_child(void)
57+
{
58+
static struct child child;
59+
int err;
60+
int c;
61+
62+
/* pipe to notify child to execute the trigger functions */
63+
if (pipe(child.go))
64+
return NULL;
65+
66+
child.pid = fork();
67+
if (child.pid < 0) {
68+
release_child(&child);
69+
errno = EINVAL;
70+
return NULL;
71+
}
72+
73+
/* child */
74+
if (child.pid == 0) {
75+
close(child.go[1]);
76+
77+
/* wait for parent's kick */
78+
err = read(child.go[0], &c, 1);
79+
if (err != 1)
80+
exit(err);
81+
82+
uprobe_multi_func_1();
83+
uprobe_multi_func_2();
84+
uprobe_multi_func_3();
85+
86+
exit(errno);
87+
}
88+
89+
return &child;
90+
}
91+
92+
static void uprobe_multi_test_run(struct uprobe_multi *skel, struct child *child)
2993
{
3094
skel->bss->uprobe_multi_func_1_addr = (__u64) uprobe_multi_func_1;
3195
skel->bss->uprobe_multi_func_2_addr = (__u64) uprobe_multi_func_2;
3296
skel->bss->uprobe_multi_func_3_addr = (__u64) uprobe_multi_func_3;
3397

3498
skel->bss->user_ptr = test_data;
35-
skel->bss->pid = getpid();
99+
100+
/*
101+
* Disable pid check in bpf program if we are pid filter test,
102+
* because the probe should be executed only by child->pid
103+
* passed at the probe attach.
104+
*/
105+
skel->bss->pid = child ? 0 : getpid();
106+
107+
if (child)
108+
kick_child(child);
36109

37110
/* trigger all probes */
38111
uprobe_multi_func_1();
@@ -52,6 +125,9 @@ static void uprobe_multi_test_run(struct uprobe_multi *skel)
52125
ASSERT_EQ(skel->bss->uretprobe_multi_func_3_result, 2, "uretprobe_multi_func_3_result");
53126

54127
ASSERT_EQ(skel->bss->uprobe_multi_sleep_result, 6, "uprobe_multi_sleep_result");
128+
129+
if (child)
130+
ASSERT_EQ(skel->bss->child_pid, child->pid, "uprobe_multi_child_pid");
55131
}
56132

57133
static void test_skel_api(void)
@@ -67,51 +143,69 @@ static void test_skel_api(void)
67143
if (!ASSERT_OK(err, "uprobe_multi__attach"))
68144
goto cleanup;
69145

70-
uprobe_multi_test_run(skel);
146+
uprobe_multi_test_run(skel, NULL);
71147

72148
cleanup:
73149
uprobe_multi__destroy(skel);
74150
}
75151

76152
static void
77-
test_attach_api(const char *binary, const char *pattern, struct bpf_uprobe_multi_opts *opts)
153+
__test_attach_api(const char *binary, const char *pattern, struct bpf_uprobe_multi_opts *opts,
154+
struct child *child)
78155
{
156+
pid_t pid = child ? child->pid : -1;
79157
struct uprobe_multi *skel = NULL;
80158

81159
skel = uprobe_multi__open_and_load();
82160
if (!ASSERT_OK_PTR(skel, "uprobe_multi__open_and_load"))
83161
goto cleanup;
84162

85163
opts->retprobe = false;
86-
skel->links.uprobe = bpf_program__attach_uprobe_multi(skel->progs.uprobe, -1,
164+
skel->links.uprobe = bpf_program__attach_uprobe_multi(skel->progs.uprobe, pid,
87165
binary, pattern, opts);
88166
if (!ASSERT_OK_PTR(skel->links.uprobe, "bpf_program__attach_uprobe_multi"))
89167
goto cleanup;
90168

91169
opts->retprobe = true;
92-
skel->links.uretprobe = bpf_program__attach_uprobe_multi(skel->progs.uretprobe, -1,
170+
skel->links.uretprobe = bpf_program__attach_uprobe_multi(skel->progs.uretprobe, pid,
93171
binary, pattern, opts);
94172
if (!ASSERT_OK_PTR(skel->links.uretprobe, "bpf_program__attach_uprobe_multi"))
95173
goto cleanup;
96174

97175
opts->retprobe = false;
98-
skel->links.uprobe_sleep = bpf_program__attach_uprobe_multi(skel->progs.uprobe_sleep, -1,
176+
skel->links.uprobe_sleep = bpf_program__attach_uprobe_multi(skel->progs.uprobe_sleep, pid,
99177
binary, pattern, opts);
100178
if (!ASSERT_OK_PTR(skel->links.uprobe_sleep, "bpf_program__attach_uprobe_multi"))
101179
goto cleanup;
102180

103181
opts->retprobe = true;
104182
skel->links.uretprobe_sleep = bpf_program__attach_uprobe_multi(skel->progs.uretprobe_sleep,
105-
-1, binary, pattern, opts);
183+
pid, binary, pattern, opts);
106184
if (!ASSERT_OK_PTR(skel->links.uretprobe_sleep, "bpf_program__attach_uprobe_multi"))
107185
goto cleanup;
108186

109-
uprobe_multi_test_run(skel);
187+
uprobe_multi_test_run(skel, child);
110188

111189
cleanup:
112190
uprobe_multi__destroy(skel);
113191
}
114192

193+
static void
194+
test_attach_api(const char *binary, const char *pattern, struct bpf_uprobe_multi_opts *opts)
195+
{
196+
struct child *child;
197+
198+
/* no pid filter */
199+
__test_attach_api(binary, pattern, opts, NULL);
200+
201+
/* pid filter */
202+
child = spawn_child();
203+
if (!ASSERT_OK_PTR(child, "spawn_child"))
204+
return;
205+
206+
__test_attach_api(binary, pattern, opts, child);
207+
}
208+
115209
static void test_attach_api_pattern(void)
116210
{
117211
LIBBPF_OPTS(bpf_uprobe_multi_opts, opts);
@@ -134,7 +228,7 @@ static void test_attach_api_syms(void)
134228
test_attach_api("/proc/self/exe", NULL, &opts);
135229
}
136230

137-
static void test_link_api(void)
231+
static void __test_link_api(struct child *child)
138232
{
139233
int prog_fd, link1_fd = -1, link2_fd = -1, link3_fd = -1, link4_fd = -1;
140234
LIBBPF_OPTS(bpf_link_create_opts, opts);
@@ -155,6 +249,7 @@ static void test_link_api(void)
155249
opts.uprobe_multi.path = path;
156250
opts.uprobe_multi.offsets = offsets;
157251
opts.uprobe_multi.cnt = ARRAY_SIZE(syms);
252+
opts.uprobe_multi.pid = child ? child->pid : 0;
158253

159254
skel = uprobe_multi__open_and_load();
160255
if (!ASSERT_OK_PTR(skel, "uprobe_multi__open_and_load"))
@@ -184,7 +279,7 @@ static void test_link_api(void)
184279
if (!ASSERT_GE(link4_fd, 0, "link4_fd"))
185280
goto cleanup;
186281

187-
uprobe_multi_test_run(skel);
282+
uprobe_multi_test_run(skel, child);
188283

189284
cleanup:
190285
if (link1_fd >= 0)
@@ -200,6 +295,21 @@ static void test_link_api(void)
200295
free(offsets);
201296
}
202297

298+
void test_link_api(void)
299+
{
300+
struct child *child;
301+
302+
/* no pid filter */
303+
__test_link_api(NULL);
304+
305+
/* pid filter */
306+
child = spawn_child();
307+
if (!ASSERT_OK_PTR(child, "spawn_child"))
308+
return;
309+
310+
__test_link_api(child);
311+
}
312+
203313
static void test_bench_attach_uprobe(void)
204314
{
205315
long attach_start_ns = 0, attach_end_ns = 0;

tools/testing/selftests/bpf/progs/uprobe_multi.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ __u64 uretprobe_multi_func_3_result = 0;
2121
__u64 uprobe_multi_sleep_result = 0;
2222

2323
int pid = 0;
24+
int child_pid = 0;
25+
2426
bool test_cookie = false;
2527
void *user_ptr = 0;
2628

@@ -34,7 +36,9 @@ static __always_inline bool verify_sleepable_user_copy(void)
3436

3537
static void uprobe_multi_check(void *ctx, bool is_return, bool is_sleep)
3638
{
37-
if (bpf_get_current_pid_tgid() >> 32 != pid)
39+
child_pid = bpf_get_current_pid_tgid() >> 32;
40+
41+
if (pid && child_pid != pid)
3842
return;
3943

4044
__u64 cookie = test_cookie ? bpf_get_attach_cookie(ctx) : 0;

0 commit comments

Comments
 (0)