1/* 2 * test_kprobes.c - simple sanity test for *probes 3 * 4 * Copyright IBM Corp. 2008 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it would be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 * the GNU General Public License for more details. 15 */ 16 17#define pr_fmt(fmt) "Kprobe smoke test: " fmt 18 19#include <linux/kernel.h> 20#include <linux/kprobes.h> 21#include <linux/random.h> 22 23#define div_factor 3 24 25static u32 rand1, preh_val, posth_val, jph_val; 26static int errors, handler_errors, num_tests; 27static u32 (*target)(u32 value); 28static u32 (*target2)(u32 value); 29 30static noinline u32 kprobe_target(u32 value) 31{ 32 return (value / div_factor); 33} 34 35static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs) 36{ 37 preh_val = (rand1 / div_factor); 38 return 0; 39} 40 41static void kp_post_handler(struct kprobe *p, struct pt_regs *regs, 42 unsigned long flags) 43{ 44 if (preh_val != (rand1 / div_factor)) { 45 handler_errors++; 46 pr_err("incorrect value in post_handler\n"); 47 } 48 posth_val = preh_val + div_factor; 49} 50 51static struct kprobe kp = { 52 .symbol_name = "kprobe_target", 53 .pre_handler = kp_pre_handler, 54 .post_handler = kp_post_handler 55}; 56 57static int test_kprobe(void) 58{ 59 int ret; 60 61 ret = register_kprobe(&kp); 62 if (ret < 0) { 63 pr_err("register_kprobe returned %d\n", ret); 64 return ret; 65 } 66 67 ret = target(rand1); 68 unregister_kprobe(&kp); 69 70 if (preh_val == 0) { 71 pr_err("kprobe pre_handler not called\n"); 72 handler_errors++; 73 } 74 75 if (posth_val == 0) { 76 pr_err("kprobe post_handler not called\n"); 77 handler_errors++; 78 } 79 80 return 0; 81} 82 83static noinline u32 kprobe_target2(u32 value) 84{ 85 return (value / div_factor) + 1; 86} 87 88static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs) 89{ 90 preh_val = (rand1 / div_factor) + 1; 91 return 0; 92} 93 94static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs, 95 unsigned long flags) 96{ 97 if (preh_val != (rand1 / div_factor) + 1) { 98 handler_errors++; 99 pr_err("incorrect value in post_handler2\n"); 100 } 101 posth_val = preh_val + div_factor; 102} 103 104static struct kprobe kp2 = { 105 .symbol_name = "kprobe_target2", 106 .pre_handler = kp_pre_handler2, 107 .post_handler = kp_post_handler2 108}; 109 110static int test_kprobes(void) 111{ 112 int ret; 113 struct kprobe *kps[2] = {&kp, &kp2}; 114 115 /* addr and flags should be cleard for reusing kprobe. */ 116 kp.addr = NULL; 117 kp.flags = 0; 118 ret = register_kprobes(kps, 2); 119 if (ret < 0) { 120 pr_err("register_kprobes returned %d\n", ret); 121 return ret; 122 } 123 124 preh_val = 0; 125 posth_val = 0; 126 ret = target(rand1); 127 128 if (preh_val == 0) { 129 pr_err("kprobe pre_handler not called\n"); 130 handler_errors++; 131 } 132 133 if (posth_val == 0) { 134 pr_err("kprobe post_handler not called\n"); 135 handler_errors++; 136 } 137 138 preh_val = 0; 139 posth_val = 0; 140 ret = target2(rand1); 141 142 if (preh_val == 0) { 143 pr_err("kprobe pre_handler2 not called\n"); 144 handler_errors++; 145 } 146 147 if (posth_val == 0) { 148 pr_err("kprobe post_handler2 not called\n"); 149 handler_errors++; 150 } 151 152 unregister_kprobes(kps, 2); 153 return 0; 154 155} 156 157static u32 j_kprobe_target(u32 value) 158{ 159 if (value != rand1) { 160 handler_errors++; 161 pr_err("incorrect value in jprobe handler\n"); 162 } 163 164 jph_val = rand1; 165 jprobe_return(); 166 return 0; 167} 168 169static struct jprobe jp = { 170 .entry = j_kprobe_target, 171 .kp.symbol_name = "kprobe_target" 172}; 173 174static int test_jprobe(void) 175{ 176 int ret; 177 178 ret = register_jprobe(&jp); 179 if (ret < 0) { 180 pr_err("register_jprobe returned %d\n", ret); 181 return ret; 182 } 183 184 ret = target(rand1); 185 unregister_jprobe(&jp); 186 if (jph_val == 0) { 187 pr_err("jprobe handler not called\n"); 188 handler_errors++; 189 } 190 191 return 0; 192} 193 194static struct jprobe jp2 = { 195 .entry = j_kprobe_target, 196 .kp.symbol_name = "kprobe_target2" 197}; 198 199static int test_jprobes(void) 200{ 201 int ret; 202 struct jprobe *jps[2] = {&jp, &jp2}; 203 204 /* addr and flags should be cleard for reusing kprobe. */ 205 jp.kp.addr = NULL; 206 jp.kp.flags = 0; 207 ret = register_jprobes(jps, 2); 208 if (ret < 0) { 209 pr_err("register_jprobes returned %d\n", ret); 210 return ret; 211 } 212 213 jph_val = 0; 214 ret = target(rand1); 215 if (jph_val == 0) { 216 pr_err("jprobe handler not called\n"); 217 handler_errors++; 218 } 219 220 jph_val = 0; 221 ret = target2(rand1); 222 if (jph_val == 0) { 223 pr_err("jprobe handler2 not called\n"); 224 handler_errors++; 225 } 226 unregister_jprobes(jps, 2); 227 228 return 0; 229} 230#ifdef CONFIG_KRETPROBES 231static u32 krph_val; 232 233static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) 234{ 235 krph_val = (rand1 / div_factor); 236 return 0; 237} 238 239static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) 240{ 241 unsigned long ret = regs_return_value(regs); 242 243 if (ret != (rand1 / div_factor)) { 244 handler_errors++; 245 pr_err("incorrect value in kretprobe handler\n"); 246 } 247 if (krph_val == 0) { 248 handler_errors++; 249 pr_err("call to kretprobe entry handler failed\n"); 250 } 251 252 krph_val = rand1; 253 return 0; 254} 255 256static struct kretprobe rp = { 257 .handler = return_handler, 258 .entry_handler = entry_handler, 259 .kp.symbol_name = "kprobe_target" 260}; 261 262static int test_kretprobe(void) 263{ 264 int ret; 265 266 ret = register_kretprobe(&rp); 267 if (ret < 0) { 268 pr_err("register_kretprobe returned %d\n", ret); 269 return ret; 270 } 271 272 ret = target(rand1); 273 unregister_kretprobe(&rp); 274 if (krph_val != rand1) { 275 pr_err("kretprobe handler not called\n"); 276 handler_errors++; 277 } 278 279 return 0; 280} 281 282static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs) 283{ 284 unsigned long ret = regs_return_value(regs); 285 286 if (ret != (rand1 / div_factor) + 1) { 287 handler_errors++; 288 pr_err("incorrect value in kretprobe handler2\n"); 289 } 290 if (krph_val == 0) { 291 handler_errors++; 292 pr_err("call to kretprobe entry handler failed\n"); 293 } 294 295 krph_val = rand1; 296 return 0; 297} 298 299static struct kretprobe rp2 = { 300 .handler = return_handler2, 301 .entry_handler = entry_handler, 302 .kp.symbol_name = "kprobe_target2" 303}; 304 305static int test_kretprobes(void) 306{ 307 int ret; 308 struct kretprobe *rps[2] = {&rp, &rp2}; 309 310 /* addr and flags should be cleard for reusing kprobe. */ 311 rp.kp.addr = NULL; 312 rp.kp.flags = 0; 313 ret = register_kretprobes(rps, 2); 314 if (ret < 0) { 315 pr_err("register_kretprobe returned %d\n", ret); 316 return ret; 317 } 318 319 krph_val = 0; 320 ret = target(rand1); 321 if (krph_val != rand1) { 322 pr_err("kretprobe handler not called\n"); 323 handler_errors++; 324 } 325 326 krph_val = 0; 327 ret = target2(rand1); 328 if (krph_val != rand1) { 329 pr_err("kretprobe handler2 not called\n"); 330 handler_errors++; 331 } 332 unregister_kretprobes(rps, 2); 333 return 0; 334} 335#endif /* CONFIG_KRETPROBES */ 336 337int init_test_probes(void) 338{ 339 int ret; 340 341 target = kprobe_target; 342 target2 = kprobe_target2; 343 344 do { 345 rand1 = prandom_u32(); 346 } while (rand1 <= div_factor); 347 348 pr_info("started\n"); 349 num_tests++; 350 ret = test_kprobe(); 351 if (ret < 0) 352 errors++; 353 354 num_tests++; 355 ret = test_kprobes(); 356 if (ret < 0) 357 errors++; 358 359 num_tests++; 360 ret = test_jprobe(); 361 if (ret < 0) 362 errors++; 363 364 num_tests++; 365 ret = test_jprobes(); 366 if (ret < 0) 367 errors++; 368 369#ifdef CONFIG_KRETPROBES 370 num_tests++; 371 ret = test_kretprobe(); 372 if (ret < 0) 373 errors++; 374 375 num_tests++; 376 ret = test_kretprobes(); 377 if (ret < 0) 378 errors++; 379#endif /* CONFIG_KRETPROBES */ 380 381 if (errors) 382 pr_err("BUG: %d out of %d tests failed\n", errors, num_tests); 383 else if (handler_errors) 384 pr_err("BUG: %d error(s) running handlers\n", handler_errors); 385 else 386 pr_info("passed successfully\n"); 387 388 return 0; 389} 390