xref: /linux/tools/testing/selftests/bpf/progs/uprobe_multi_session.c (revision 25768de50b1f2dbb6ea44bd5148a87fe2c9c3688)
1*4856ecb1SJiri Olsa // SPDX-License-Identifier: GPL-2.0
2*4856ecb1SJiri Olsa #include <linux/bpf.h>
3*4856ecb1SJiri Olsa #include <bpf/bpf_helpers.h>
4*4856ecb1SJiri Olsa #include <bpf/bpf_tracing.h>
5*4856ecb1SJiri Olsa #include <stdbool.h>
6*4856ecb1SJiri Olsa #include "bpf_kfuncs.h"
7*4856ecb1SJiri Olsa #include "bpf_misc.h"
8*4856ecb1SJiri Olsa 
9*4856ecb1SJiri Olsa char _license[] SEC("license") = "GPL";
10*4856ecb1SJiri Olsa 
11*4856ecb1SJiri Olsa __u64 uprobe_multi_func_1_addr = 0;
12*4856ecb1SJiri Olsa __u64 uprobe_multi_func_2_addr = 0;
13*4856ecb1SJiri Olsa __u64 uprobe_multi_func_3_addr = 0;
14*4856ecb1SJiri Olsa 
15*4856ecb1SJiri Olsa __u64 uprobe_session_result[3] = {};
16*4856ecb1SJiri Olsa __u64 uprobe_multi_sleep_result = 0;
17*4856ecb1SJiri Olsa 
18*4856ecb1SJiri Olsa void *user_ptr = 0;
19*4856ecb1SJiri Olsa int pid = 0;
20*4856ecb1SJiri Olsa 
21*4856ecb1SJiri Olsa static int uprobe_multi_check(void *ctx, bool is_return)
22*4856ecb1SJiri Olsa {
23*4856ecb1SJiri Olsa 	const __u64 funcs[] = {
24*4856ecb1SJiri Olsa 		uprobe_multi_func_1_addr,
25*4856ecb1SJiri Olsa 		uprobe_multi_func_2_addr,
26*4856ecb1SJiri Olsa 		uprobe_multi_func_3_addr,
27*4856ecb1SJiri Olsa 	};
28*4856ecb1SJiri Olsa 	unsigned int i;
29*4856ecb1SJiri Olsa 	__u64 addr;
30*4856ecb1SJiri Olsa 
31*4856ecb1SJiri Olsa 	if (bpf_get_current_pid_tgid() >> 32 != pid)
32*4856ecb1SJiri Olsa 		return 1;
33*4856ecb1SJiri Olsa 
34*4856ecb1SJiri Olsa 	addr = bpf_get_func_ip(ctx);
35*4856ecb1SJiri Olsa 
36*4856ecb1SJiri Olsa 	for (i = 0; i < ARRAY_SIZE(funcs); i++) {
37*4856ecb1SJiri Olsa 		if (funcs[i] == addr) {
38*4856ecb1SJiri Olsa 			uprobe_session_result[i]++;
39*4856ecb1SJiri Olsa 			break;
40*4856ecb1SJiri Olsa 		}
41*4856ecb1SJiri Olsa 	}
42*4856ecb1SJiri Olsa 
43*4856ecb1SJiri Olsa 	/* only uprobe_multi_func_2 executes return probe */
44*4856ecb1SJiri Olsa 	if ((addr == uprobe_multi_func_1_addr) ||
45*4856ecb1SJiri Olsa 	    (addr == uprobe_multi_func_3_addr))
46*4856ecb1SJiri Olsa 		return 1;
47*4856ecb1SJiri Olsa 
48*4856ecb1SJiri Olsa 	return 0;
49*4856ecb1SJiri Olsa }
50*4856ecb1SJiri Olsa 
51*4856ecb1SJiri Olsa SEC("uprobe.session//proc/self/exe:uprobe_multi_func_*")
52*4856ecb1SJiri Olsa int uprobe(struct pt_regs *ctx)
53*4856ecb1SJiri Olsa {
54*4856ecb1SJiri Olsa 	return uprobe_multi_check(ctx, bpf_session_is_return());
55*4856ecb1SJiri Olsa }
56*4856ecb1SJiri Olsa 
57*4856ecb1SJiri Olsa static __always_inline bool verify_sleepable_user_copy(void)
58*4856ecb1SJiri Olsa {
59*4856ecb1SJiri Olsa 	char data[9];
60*4856ecb1SJiri Olsa 
61*4856ecb1SJiri Olsa 	bpf_copy_from_user(data, sizeof(data), user_ptr);
62*4856ecb1SJiri Olsa 	return bpf_strncmp(data, sizeof(data), "test_data") == 0;
63*4856ecb1SJiri Olsa }
64*4856ecb1SJiri Olsa 
65*4856ecb1SJiri Olsa SEC("uprobe.session.s//proc/self/exe:uprobe_multi_func_*")
66*4856ecb1SJiri Olsa int uprobe_sleepable(struct pt_regs *ctx)
67*4856ecb1SJiri Olsa {
68*4856ecb1SJiri Olsa 	if (verify_sleepable_user_copy())
69*4856ecb1SJiri Olsa 		uprobe_multi_sleep_result++;
70*4856ecb1SJiri Olsa 	return uprobe_multi_check(ctx, bpf_session_is_return());
71*4856ecb1SJiri Olsa }
72