• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * test_kprobes.c - simple sanity test for *probes
4  *
5  * Copyright IBM Corp. 2008
6  */
7 
8 #define pr_fmt(fmt) "Kprobe smoke test: " fmt
9 
10 #include <linux/kernel.h>
11 #include <linux/kprobes.h>
12 #include <linux/random.h>
13 
14 #define div_factor 3
15 
16 static u32 rand1, preh_val, posth_val;
17 static int errors, handler_errors, num_tests;
18 static u32 (*target)(u32 value);
19 static u32 (*target2)(u32 value);
20 
kprobe_target(u32 value)21 static noinline u32 kprobe_target(u32 value)
22 {
23 	return (value / div_factor);
24 }
25 
kp_pre_handler(struct kprobe * p,struct pt_regs * regs)26 static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
27 {
28 	if (preemptible()) {
29 		handler_errors++;
30 		pr_err("pre-handler is preemptible\n");
31 	}
32 	preh_val = (rand1 / div_factor);
33 	return 0;
34 }
35 
kp_post_handler(struct kprobe * p,struct pt_regs * regs,unsigned long flags)36 static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
37 		unsigned long flags)
38 {
39 	if (preemptible()) {
40 		handler_errors++;
41 		pr_err("post-handler is preemptible\n");
42 	}
43 	if (preh_val != (rand1 / div_factor)) {
44 		handler_errors++;
45 		pr_err("incorrect value in post_handler\n");
46 	}
47 	posth_val = preh_val + div_factor;
48 }
49 
50 static struct kprobe kp = {
51 	.symbol_name = "kprobe_target",
52 	.pre_handler = kp_pre_handler,
53 	.post_handler = kp_post_handler
54 };
55 
test_kprobe(void)56 static int test_kprobe(void)
57 {
58 	int ret;
59 
60 	ret = register_kprobe(&kp);
61 	if (ret < 0) {
62 		pr_err("register_kprobe returned %d\n", ret);
63 		return ret;
64 	}
65 
66 	ret = target(rand1);
67 	unregister_kprobe(&kp);
68 
69 	if (preh_val == 0) {
70 		pr_err("kprobe pre_handler not called\n");
71 		handler_errors++;
72 	}
73 
74 	if (posth_val == 0) {
75 		pr_err("kprobe post_handler not called\n");
76 		handler_errors++;
77 	}
78 
79 	return 0;
80 }
81 
kprobe_target2(u32 value)82 static noinline u32 kprobe_target2(u32 value)
83 {
84 	return (value / div_factor) + 1;
85 }
86 
kp_pre_handler2(struct kprobe * p,struct pt_regs * regs)87 static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
88 {
89 	preh_val = (rand1 / div_factor) + 1;
90 	return 0;
91 }
92 
kp_post_handler2(struct kprobe * p,struct pt_regs * regs,unsigned long flags)93 static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
94 		unsigned long flags)
95 {
96 	if (preh_val != (rand1 / div_factor) + 1) {
97 		handler_errors++;
98 		pr_err("incorrect value in post_handler2\n");
99 	}
100 	posth_val = preh_val + div_factor;
101 }
102 
103 static struct kprobe kp2 = {
104 	.symbol_name = "kprobe_target2",
105 	.pre_handler = kp_pre_handler2,
106 	.post_handler = kp_post_handler2
107 };
108 
test_kprobes(void)109 static int test_kprobes(void)
110 {
111 	int ret;
112 	struct kprobe *kps[2] = {&kp, &kp2};
113 
114 	/* addr and flags should be cleard for reusing kprobe. */
115 	kp.addr = NULL;
116 	kp.flags = 0;
117 	ret = register_kprobes(kps, 2);
118 	if (ret < 0) {
119 		pr_err("register_kprobes returned %d\n", ret);
120 		return ret;
121 	}
122 
123 	preh_val = 0;
124 	posth_val = 0;
125 	ret = target(rand1);
126 
127 	if (preh_val == 0) {
128 		pr_err("kprobe pre_handler not called\n");
129 		handler_errors++;
130 	}
131 
132 	if (posth_val == 0) {
133 		pr_err("kprobe post_handler not called\n");
134 		handler_errors++;
135 	}
136 
137 	preh_val = 0;
138 	posth_val = 0;
139 	ret = target2(rand1);
140 
141 	if (preh_val == 0) {
142 		pr_err("kprobe pre_handler2 not called\n");
143 		handler_errors++;
144 	}
145 
146 	if (posth_val == 0) {
147 		pr_err("kprobe post_handler2 not called\n");
148 		handler_errors++;
149 	}
150 
151 	unregister_kprobes(kps, 2);
152 	return 0;
153 
154 }
155 
156 #ifdef CONFIG_KRETPROBES
157 static u32 krph_val;
158 
entry_handler(struct kretprobe_instance * ri,struct pt_regs * regs)159 static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
160 {
161 	if (preemptible()) {
162 		handler_errors++;
163 		pr_err("kretprobe entry handler is preemptible\n");
164 	}
165 	krph_val = (rand1 / div_factor);
166 	return 0;
167 }
168 
return_handler(struct kretprobe_instance * ri,struct pt_regs * regs)169 static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
170 {
171 	unsigned long ret = regs_return_value(regs);
172 
173 	if (preemptible()) {
174 		handler_errors++;
175 		pr_err("kretprobe return handler is preemptible\n");
176 	}
177 	if (ret != (rand1 / div_factor)) {
178 		handler_errors++;
179 		pr_err("incorrect value in kretprobe handler\n");
180 	}
181 	if (krph_val == 0) {
182 		handler_errors++;
183 		pr_err("call to kretprobe entry handler failed\n");
184 	}
185 
186 	krph_val = rand1;
187 	return 0;
188 }
189 
190 static struct kretprobe rp = {
191 	.handler	= return_handler,
192 	.entry_handler  = entry_handler,
193 	.kp.symbol_name = "kprobe_target"
194 };
195 
test_kretprobe(void)196 static int test_kretprobe(void)
197 {
198 	int ret;
199 
200 	ret = register_kretprobe(&rp);
201 	if (ret < 0) {
202 		pr_err("register_kretprobe returned %d\n", ret);
203 		return ret;
204 	}
205 
206 	ret = target(rand1);
207 	unregister_kretprobe(&rp);
208 	if (krph_val != rand1) {
209 		pr_err("kretprobe handler not called\n");
210 		handler_errors++;
211 	}
212 
213 	return 0;
214 }
215 
return_handler2(struct kretprobe_instance * ri,struct pt_regs * regs)216 static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
217 {
218 	unsigned long ret = regs_return_value(regs);
219 
220 	if (ret != (rand1 / div_factor) + 1) {
221 		handler_errors++;
222 		pr_err("incorrect value in kretprobe handler2\n");
223 	}
224 	if (krph_val == 0) {
225 		handler_errors++;
226 		pr_err("call to kretprobe entry handler failed\n");
227 	}
228 
229 	krph_val = rand1;
230 	return 0;
231 }
232 
233 static struct kretprobe rp2 = {
234 	.handler	= return_handler2,
235 	.entry_handler  = entry_handler,
236 	.kp.symbol_name = "kprobe_target2"
237 };
238 
test_kretprobes(void)239 static int test_kretprobes(void)
240 {
241 	int ret;
242 	struct kretprobe *rps[2] = {&rp, &rp2};
243 
244 	/* addr and flags should be cleard for reusing kprobe. */
245 	rp.kp.addr = NULL;
246 	rp.kp.flags = 0;
247 	ret = register_kretprobes(rps, 2);
248 	if (ret < 0) {
249 		pr_err("register_kretprobe returned %d\n", ret);
250 		return ret;
251 	}
252 
253 	krph_val = 0;
254 	ret = target(rand1);
255 	if (krph_val != rand1) {
256 		pr_err("kretprobe handler not called\n");
257 		handler_errors++;
258 	}
259 
260 	krph_val = 0;
261 	ret = target2(rand1);
262 	if (krph_val != rand1) {
263 		pr_err("kretprobe handler2 not called\n");
264 		handler_errors++;
265 	}
266 	unregister_kretprobes(rps, 2);
267 	return 0;
268 }
269 #endif /* CONFIG_KRETPROBES */
270 
init_test_probes(void)271 int init_test_probes(void)
272 {
273 	int ret;
274 
275 	target = kprobe_target;
276 	target2 = kprobe_target2;
277 
278 	do {
279 		rand1 = prandom_u32();
280 	} while (rand1 <= div_factor);
281 
282 	pr_info("started\n");
283 	num_tests++;
284 	ret = test_kprobe();
285 	if (ret < 0)
286 		errors++;
287 
288 	num_tests++;
289 	ret = test_kprobes();
290 	if (ret < 0)
291 		errors++;
292 
293 #ifdef CONFIG_KRETPROBES
294 	num_tests++;
295 	ret = test_kretprobe();
296 	if (ret < 0)
297 		errors++;
298 
299 	num_tests++;
300 	ret = test_kretprobes();
301 	if (ret < 0)
302 		errors++;
303 #endif /* CONFIG_KRETPROBES */
304 
305 	if (errors)
306 		pr_err("BUG: %d out of %d tests failed\n", errors, num_tests);
307 	else if (handler_errors)
308 		pr_err("BUG: %d error(s) running handlers\n", handler_errors);
309 	else
310 		pr_info("passed successfully\n");
311 
312 	return 0;
313 }
314