linux/kernel/test_kprobes.c
<<
>>
Prefs
   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