The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kernel/test_kprobes.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 #include <linux/kernel.h>
   18 #include <linux/kprobes.h>
   19 #include <linux/random.h>
   20 
   21 #define div_factor 3
   22 
   23 static u32 rand1, preh_val, posth_val, jph_val;
   24 static int errors, handler_errors, num_tests;
   25 static u32 (*target)(u32 value);
   26 static u32 (*target2)(u32 value);
   27 
   28 static noinline u32 kprobe_target(u32 value)
   29 {
   30         return (value / div_factor);
   31 }
   32 
   33 static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
   34 {
   35         preh_val = (rand1 / div_factor);
   36         return 0;
   37 }
   38 
   39 static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
   40                 unsigned long flags)
   41 {
   42         if (preh_val != (rand1 / div_factor)) {
   43                 handler_errors++;
   44                 printk(KERN_ERR "Kprobe smoke test failed: "
   45                                 "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                 printk(KERN_ERR "Kprobe smoke test failed: "
   63                                 "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                 printk(KERN_ERR "Kprobe smoke test failed: "
   72                                 "kprobe pre_handler not called\n");
   73                 handler_errors++;
   74         }
   75 
   76         if (posth_val == 0) {
   77                 printk(KERN_ERR "Kprobe smoke test failed: "
   78                                 "kprobe post_handler not called\n");
   79                 handler_errors++;
   80         }
   81 
   82         return 0;
   83 }
   84 
   85 static noinline u32 kprobe_target2(u32 value)
   86 {
   87         return (value / div_factor) + 1;
   88 }
   89 
   90 static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
   91 {
   92         preh_val = (rand1 / div_factor) + 1;
   93         return 0;
   94 }
   95 
   96 static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
   97                 unsigned long flags)
   98 {
   99         if (preh_val != (rand1 / div_factor) + 1) {
  100                 handler_errors++;
  101                 printk(KERN_ERR "Kprobe smoke test failed: "
  102                                 "incorrect value in post_handler2\n");
  103         }
  104         posth_val = preh_val + div_factor;
  105 }
  106 
  107 static struct kprobe kp2 = {
  108         .symbol_name = "kprobe_target2",
  109         .pre_handler = kp_pre_handler2,
  110         .post_handler = kp_post_handler2
  111 };
  112 
  113 static int test_kprobes(void)
  114 {
  115         int ret;
  116         struct kprobe *kps[2] = {&kp, &kp2};
  117 
  118         /* addr and flags should be cleard for reusing kprobe. */
  119         kp.addr = NULL;
  120         kp.flags = 0;
  121         ret = register_kprobes(kps, 2);
  122         if (ret < 0) {
  123                 printk(KERN_ERR "Kprobe smoke test failed: "
  124                                 "register_kprobes returned %d\n", ret);
  125                 return ret;
  126         }
  127 
  128         preh_val = 0;
  129         posth_val = 0;
  130         ret = target(rand1);
  131 
  132         if (preh_val == 0) {
  133                 printk(KERN_ERR "Kprobe smoke test failed: "
  134                                 "kprobe pre_handler not called\n");
  135                 handler_errors++;
  136         }
  137 
  138         if (posth_val == 0) {
  139                 printk(KERN_ERR "Kprobe smoke test failed: "
  140                                 "kprobe post_handler not called\n");
  141                 handler_errors++;
  142         }
  143 
  144         preh_val = 0;
  145         posth_val = 0;
  146         ret = target2(rand1);
  147 
  148         if (preh_val == 0) {
  149                 printk(KERN_ERR "Kprobe smoke test failed: "
  150                                 "kprobe pre_handler2 not called\n");
  151                 handler_errors++;
  152         }
  153 
  154         if (posth_val == 0) {
  155                 printk(KERN_ERR "Kprobe smoke test failed: "
  156                                 "kprobe post_handler2 not called\n");
  157                 handler_errors++;
  158         }
  159 
  160         unregister_kprobes(kps, 2);
  161         return 0;
  162 
  163 }
  164 
  165 static u32 j_kprobe_target(u32 value)
  166 {
  167         if (value != rand1) {
  168                 handler_errors++;
  169                 printk(KERN_ERR "Kprobe smoke test failed: "
  170                                 "incorrect value in jprobe handler\n");
  171         }
  172 
  173         jph_val = rand1;
  174         jprobe_return();
  175         return 0;
  176 }
  177 
  178 static struct jprobe jp = {
  179         .entry          = j_kprobe_target,
  180         .kp.symbol_name = "kprobe_target"
  181 };
  182 
  183 static int test_jprobe(void)
  184 {
  185         int ret;
  186 
  187         ret = register_jprobe(&jp);
  188         if (ret < 0) {
  189                 printk(KERN_ERR "Kprobe smoke test failed: "
  190                                 "register_jprobe returned %d\n", ret);
  191                 return ret;
  192         }
  193 
  194         ret = target(rand1);
  195         unregister_jprobe(&jp);
  196         if (jph_val == 0) {
  197                 printk(KERN_ERR "Kprobe smoke test failed: "
  198                                 "jprobe handler not called\n");
  199                 handler_errors++;
  200         }
  201 
  202         return 0;
  203 }
  204 
  205 static struct jprobe jp2 = {
  206         .entry          = j_kprobe_target,
  207         .kp.symbol_name = "kprobe_target2"
  208 };
  209 
  210 static int test_jprobes(void)
  211 {
  212         int ret;
  213         struct jprobe *jps[2] = {&jp, &jp2};
  214 
  215         /* addr and flags should be cleard for reusing kprobe. */
  216         jp.kp.addr = NULL;
  217         jp.kp.flags = 0;
  218         ret = register_jprobes(jps, 2);
  219         if (ret < 0) {
  220                 printk(KERN_ERR "Kprobe smoke test failed: "
  221                                 "register_jprobes returned %d\n", ret);
  222                 return ret;
  223         }
  224 
  225         jph_val = 0;
  226         ret = target(rand1);
  227         if (jph_val == 0) {
  228                 printk(KERN_ERR "Kprobe smoke test failed: "
  229                                 "jprobe handler not called\n");
  230                 handler_errors++;
  231         }
  232 
  233         jph_val = 0;
  234         ret = target2(rand1);
  235         if (jph_val == 0) {
  236                 printk(KERN_ERR "Kprobe smoke test failed: "
  237                                 "jprobe handler2 not called\n");
  238                 handler_errors++;
  239         }
  240         unregister_jprobes(jps, 2);
  241 
  242         return 0;
  243 }
  244 #ifdef CONFIG_KRETPROBES
  245 static u32 krph_val;
  246 
  247 static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  248 {
  249         krph_val = (rand1 / div_factor);
  250         return 0;
  251 }
  252 
  253 static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  254 {
  255         unsigned long ret = regs_return_value(regs);
  256 
  257         if (ret != (rand1 / div_factor)) {
  258                 handler_errors++;
  259                 printk(KERN_ERR "Kprobe smoke test failed: "
  260                                 "incorrect value in kretprobe handler\n");
  261         }
  262         if (krph_val == 0) {
  263                 handler_errors++;
  264                 printk(KERN_ERR "Kprobe smoke test failed: "
  265                                 "call to kretprobe entry handler failed\n");
  266         }
  267 
  268         krph_val = rand1;
  269         return 0;
  270 }
  271 
  272 static struct kretprobe rp = {
  273         .handler        = return_handler,
  274         .entry_handler  = entry_handler,
  275         .kp.symbol_name = "kprobe_target"
  276 };
  277 
  278 static int test_kretprobe(void)
  279 {
  280         int ret;
  281 
  282         ret = register_kretprobe(&rp);
  283         if (ret < 0) {
  284                 printk(KERN_ERR "Kprobe smoke test failed: "
  285                                 "register_kretprobe returned %d\n", ret);
  286                 return ret;
  287         }
  288 
  289         ret = target(rand1);
  290         unregister_kretprobe(&rp);
  291         if (krph_val != rand1) {
  292                 printk(KERN_ERR "Kprobe smoke test failed: "
  293                                 "kretprobe handler not called\n");
  294                 handler_errors++;
  295         }
  296 
  297         return 0;
  298 }
  299 
  300 static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
  301 {
  302         unsigned long ret = regs_return_value(regs);
  303 
  304         if (ret != (rand1 / div_factor) + 1) {
  305                 handler_errors++;
  306                 printk(KERN_ERR "Kprobe smoke test failed: "
  307                                 "incorrect value in kretprobe handler2\n");
  308         }
  309         if (krph_val == 0) {
  310                 handler_errors++;
  311                 printk(KERN_ERR "Kprobe smoke test failed: "
  312                                 "call to kretprobe entry handler failed\n");
  313         }
  314 
  315         krph_val = rand1;
  316         return 0;
  317 }
  318 
  319 static struct kretprobe rp2 = {
  320         .handler        = return_handler2,
  321         .entry_handler  = entry_handler,
  322         .kp.symbol_name = "kprobe_target2"
  323 };
  324 
  325 static int test_kretprobes(void)
  326 {
  327         int ret;
  328         struct kretprobe *rps[2] = {&rp, &rp2};
  329 
  330         /* addr and flags should be cleard for reusing kprobe. */
  331         rp.kp.addr = NULL;
  332         rp.kp.flags = 0;
  333         ret = register_kretprobes(rps, 2);
  334         if (ret < 0) {
  335                 printk(KERN_ERR "Kprobe smoke test failed: "
  336                                 "register_kretprobe returned %d\n", ret);
  337                 return ret;
  338         }
  339 
  340         krph_val = 0;
  341         ret = target(rand1);
  342         if (krph_val != rand1) {
  343                 printk(KERN_ERR "Kprobe smoke test failed: "
  344                                 "kretprobe handler not called\n");
  345                 handler_errors++;
  346         }
  347 
  348         krph_val = 0;
  349         ret = target2(rand1);
  350         if (krph_val != rand1) {
  351                 printk(KERN_ERR "Kprobe smoke test failed: "
  352                                 "kretprobe handler2 not called\n");
  353                 handler_errors++;
  354         }
  355         unregister_kretprobes(rps, 2);
  356         return 0;
  357 }
  358 #endif /* CONFIG_KRETPROBES */
  359 
  360 int init_test_probes(void)
  361 {
  362         int ret;
  363 
  364         target = kprobe_target;
  365         target2 = kprobe_target2;
  366 
  367         do {
  368                 rand1 = random32();
  369         } while (rand1 <= div_factor);
  370 
  371         printk(KERN_INFO "Kprobe smoke test started\n");
  372         num_tests++;
  373         ret = test_kprobe();
  374         if (ret < 0)
  375                 errors++;
  376 
  377         num_tests++;
  378         ret = test_kprobes();
  379         if (ret < 0)
  380                 errors++;
  381 
  382         num_tests++;
  383         ret = test_jprobe();
  384         if (ret < 0)
  385                 errors++;
  386 
  387         num_tests++;
  388         ret = test_jprobes();
  389         if (ret < 0)
  390                 errors++;
  391 
  392 #ifdef CONFIG_KRETPROBES
  393         num_tests++;
  394         ret = test_kretprobe();
  395         if (ret < 0)
  396                 errors++;
  397 
  398         num_tests++;
  399         ret = test_kretprobes();
  400         if (ret < 0)
  401                 errors++;
  402 #endif /* CONFIG_KRETPROBES */
  403 
  404         if (errors)
  405                 printk(KERN_ERR "BUG: Kprobe smoke test: %d out of "
  406                                 "%d tests failed\n", errors, num_tests);
  407         else if (handler_errors)
  408                 printk(KERN_ERR "BUG: Kprobe smoke test: %d error(s) "
  409                                 "running handlers\n", handler_errors);
  410         else
  411                 printk(KERN_INFO "Kprobe smoke test passed successfully\n");
  412 
  413         return 0;
  414 }

Cache object: 985c843371299f073926d153e2a3cd94


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.