linux/kernel/test_kprobes.c
<<
>>
Prefs
   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
  16static u32 rand1, preh_val, posth_val;
  17static int errors, handler_errors, num_tests;
  18static u32 (*target)(u32 value);
  19static u32 (*target2)(u32 value);
  20
  21static noinline u32 kprobe_target(u32 value)
  22{
  23        return (value / div_factor);
  24}
  25
  26static 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
  36static 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
  50static struct kprobe kp = {
  51        .symbol_name = "kprobe_target",
  52        .pre_handler = kp_pre_handler,
  53        .post_handler = kp_post_handler
  54};
  55
  56static 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
  82static noinline u32 kprobe_target2(u32 value)
  83{
  84        return (value / div_factor) + 1;
  85}
  86
  87static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
  88{
  89        preh_val = (rand1 / div_factor) + 1;
  90        return 0;
  91}
  92
  93static 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
 103static struct kprobe kp2 = {
 104        .symbol_name = "kprobe_target2",
 105        .pre_handler = kp_pre_handler2,
 106        .post_handler = kp_post_handler2
 107};
 108
 109static 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
 157static u32 krph_val;
 158
 159static 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
 169static 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
 190static struct kretprobe rp = {
 191        .handler        = return_handler,
 192        .entry_handler  = entry_handler,
 193        .kp.symbol_name = "kprobe_target"
 194};
 195
 196static 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
 216static 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
 233static struct kretprobe rp2 = {
 234        .handler        = return_handler2,
 235        .entry_handler  = entry_handler,
 236        .kp.symbol_name = "kprobe_target2"
 237};
 238
 239static 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
 271int 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