root/kernel/test_kprobes.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kprobe_target
  2. kp_pre_handler
  3. kp_post_handler
  4. test_kprobe
  5. kprobe_target2
  6. kp_pre_handler2
  7. kp_post_handler2
  8. test_kprobes
  9. entry_handler
  10. return_handler
  11. test_kretprobe
  12. return_handler2
  13. test_kretprobes
  14. init_test_probes

   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 
  21 static noinline u32 kprobe_target(u32 value)
  22 {
  23         return (value / div_factor);
  24 }
  25 
  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 
  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 
  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 
  82 static noinline u32 kprobe_target2(u32 value)
  83 {
  84         return (value / div_factor) + 1;
  85 }
  86 
  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 
  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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 }

/* [<][>][^][v][top][bottom][index][help] */