xref: /linux/tools/testing/selftests/bpf/progs/test_attach_probe.c (revision 50f2944009a25bb39a09f2f7bab64a73ce928bef)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2017 Facebook
3 
4 #include <linux/ptrace.h>
5 #include <linux/bpf.h>
6 #include <bpf/bpf_helpers.h>
7 #include <bpf/bpf_tracing.h>
8 #include <stdbool.h>
9 #include "bpf_misc.h"
10 
11 int kprobe_res = 0;
12 int kprobe2_res = 0;
13 int kretprobe_res = 0;
14 int kretprobe2_res = 0;
15 int uprobe_res = 0;
16 int uretprobe_res = 0;
17 int uprobe_byname_res = 0;
18 int uretprobe_byname_res = 0;
19 int uprobe_byname2_res = 0;
20 int uretprobe_byname2_res = 0;
21 int uprobe_byname3_sleepable_res = 0;
22 int uprobe_byname3_res = 0;
23 int uretprobe_byname3_sleepable_res = 0;
24 int uretprobe_byname3_res = 0;
25 void *user_ptr = 0;
26 
27 SEC("kprobe")
28 int handle_kprobe(struct pt_regs *ctx)
29 {
30 	kprobe_res = 1;
31 	return 0;
32 }
33 
34 SEC("kprobe/" SYS_PREFIX "sys_nanosleep")
35 int BPF_KPROBE(handle_kprobe_auto)
36 {
37 	kprobe2_res = 11;
38 	return 0;
39 }
40 
41 /**
42  * This program will be manually made sleepable on the userspace side
43  * and should thus be unattachable.
44  */
45 SEC("kprobe/" SYS_PREFIX "sys_nanosleep")
46 int handle_kprobe_sleepable(struct pt_regs *ctx)
47 {
48 	kprobe_res = 2;
49 	return 0;
50 }
51 
52 SEC("kretprobe")
53 int handle_kretprobe(struct pt_regs *ctx)
54 {
55 	kretprobe_res = 2;
56 	return 0;
57 }
58 
59 SEC("kretprobe/" SYS_PREFIX "sys_nanosleep")
60 int BPF_KRETPROBE(handle_kretprobe_auto)
61 {
62 	kretprobe2_res = 22;
63 	return 0;
64 }
65 
66 SEC("uprobe")
67 int handle_uprobe(struct pt_regs *ctx)
68 {
69 	uprobe_res = 3;
70 	return 0;
71 }
72 
73 SEC("uretprobe")
74 int handle_uretprobe(struct pt_regs *ctx)
75 {
76 	uretprobe_res = 4;
77 	return 0;
78 }
79 
80 SEC("uprobe")
81 int handle_uprobe_byname(struct pt_regs *ctx)
82 {
83 	uprobe_byname_res = 5;
84 	return 0;
85 }
86 
87 /* use auto-attach format for section definition. */
88 SEC("uretprobe//proc/self/exe:trigger_func2")
89 int handle_uretprobe_byname(struct pt_regs *ctx)
90 {
91 	uretprobe_byname_res = 6;
92 	return 0;
93 }
94 
95 SEC("uprobe")
96 int handle_uprobe_byname2(struct pt_regs *ctx)
97 {
98 	unsigned int size = PT_REGS_PARM1(ctx);
99 
100 	/* verify malloc size */
101 	if (size == 1)
102 		uprobe_byname2_res = 7;
103 	return 0;
104 }
105 
106 SEC("uretprobe")
107 int handle_uretprobe_byname2(struct pt_regs *ctx)
108 {
109 	uretprobe_byname2_res = 8;
110 	return 0;
111 }
112 
113 static __always_inline bool verify_sleepable_user_copy(void)
114 {
115 	char data[9];
116 
117 	bpf_copy_from_user(data, sizeof(data), user_ptr);
118 	return bpf_strncmp(data, sizeof(data), "test_data") == 0;
119 }
120 
121 SEC("uprobe.s//proc/self/exe:trigger_func3")
122 int handle_uprobe_byname3_sleepable(struct pt_regs *ctx)
123 {
124 	if (verify_sleepable_user_copy())
125 		uprobe_byname3_sleepable_res = 9;
126 	return 0;
127 }
128 
129 /**
130  * same target as the uprobe.s above to force sleepable and non-sleepable
131  * programs in the same bpf_prog_array
132  */
133 SEC("uprobe//proc/self/exe:trigger_func3")
134 int handle_uprobe_byname3(struct pt_regs *ctx)
135 {
136 	uprobe_byname3_res = 10;
137 	return 0;
138 }
139 
140 SEC("uretprobe.s//proc/self/exe:trigger_func3")
141 int handle_uretprobe_byname3_sleepable(struct pt_regs *ctx)
142 {
143 	if (verify_sleepable_user_copy())
144 		uretprobe_byname3_sleepable_res = 11;
145 	return 0;
146 }
147 
148 SEC("uretprobe//proc/self/exe:trigger_func3")
149 int handle_uretprobe_byname3(struct pt_regs *ctx)
150 {
151 	uretprobe_byname3_res = 12;
152 	return 0;
153 }
154 
155 
156 char _license[] SEC("license") = "GPL";
157