linux/lib/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#include <linux/kernel.h>
   9#include <linux/kprobes.h>
  10#include <linux/random.h>
  11#include <kunit/test.h>
  12
  13#define div_factor 3
  14
  15static u32 rand1, preh_val, posth_val;
  16static u32 (*target)(u32 value);
  17static u32 (*target2)(u32 value);
  18static struct kunit *current_test;
  19
  20static unsigned long (*internal_target)(void);
  21static unsigned long (*stacktrace_target)(void);
  22static unsigned long (*stacktrace_driver)(void);
  23static unsigned long target_return_address[2];
  24
  25static noinline u32 kprobe_target(u32 value)
  26{
  27        return (value / div_factor);
  28}
  29
  30static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
  31{
  32        KUNIT_EXPECT_FALSE(current_test, preemptible());
  33        preh_val = (rand1 / div_factor);
  34        return 0;
  35}
  36
  37static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
  38                unsigned long flags)
  39{
  40        KUNIT_EXPECT_FALSE(current_test, preemptible());
  41        KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor));
  42        posth_val = preh_val + div_factor;
  43}
  44
  45static struct kprobe kp = {
  46        .symbol_name = "kprobe_target",
  47        .pre_handler = kp_pre_handler,
  48        .post_handler = kp_post_handler
  49};
  50
  51static void test_kprobe(struct kunit *test)
  52{
  53        current_test = test;
  54        KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp));
  55        target(rand1);
  56        unregister_kprobe(&kp);
  57        KUNIT_EXPECT_NE(test, 0, preh_val);
  58        KUNIT_EXPECT_NE(test, 0, posth_val);
  59}
  60
  61static noinline u32 kprobe_target2(u32 value)
  62{
  63        return (value / div_factor) + 1;
  64}
  65
  66static noinline unsigned long kprobe_stacktrace_internal_target(void)
  67{
  68        if (!target_return_address[0])
  69                target_return_address[0] = (unsigned long)__builtin_return_address(0);
  70        return target_return_address[0];
  71}
  72
  73static noinline unsigned long kprobe_stacktrace_target(void)
  74{
  75        if (!target_return_address[1])
  76                target_return_address[1] = (unsigned long)__builtin_return_address(0);
  77
  78        if (internal_target)
  79                internal_target();
  80
  81        return target_return_address[1];
  82}
  83
  84static noinline unsigned long kprobe_stacktrace_driver(void)
  85{
  86        if (stacktrace_target)
  87                stacktrace_target();
  88
  89        /* This is for preventing inlining the function */
  90        return (unsigned long)__builtin_return_address(0);
  91}
  92
  93static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
  94{
  95        preh_val = (rand1 / div_factor) + 1;
  96        return 0;
  97}
  98
  99static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
 100                unsigned long flags)
 101{
 102        KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor) + 1);
 103        posth_val = preh_val + div_factor;
 104}
 105
 106static struct kprobe kp2 = {
 107        .symbol_name = "kprobe_target2",
 108        .pre_handler = kp_pre_handler2,
 109        .post_handler = kp_post_handler2
 110};
 111
 112static void test_kprobes(struct kunit *test)
 113{
 114        struct kprobe *kps[2] = {&kp, &kp2};
 115
 116        current_test = test;
 117
 118        /* addr and flags should be cleard for reusing kprobe. */
 119        kp.addr = NULL;
 120        kp.flags = 0;
 121
 122        KUNIT_EXPECT_EQ(test, 0, register_kprobes(kps, 2));
 123        preh_val = 0;
 124        posth_val = 0;
 125        target(rand1);
 126
 127        KUNIT_EXPECT_NE(test, 0, preh_val);
 128        KUNIT_EXPECT_NE(test, 0, posth_val);
 129
 130        preh_val = 0;
 131        posth_val = 0;
 132        target2(rand1);
 133
 134        KUNIT_EXPECT_NE(test, 0, preh_val);
 135        KUNIT_EXPECT_NE(test, 0, posth_val);
 136        unregister_kprobes(kps, 2);
 137}
 138
 139#ifdef CONFIG_KRETPROBES
 140static u32 krph_val;
 141
 142static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 143{
 144        KUNIT_EXPECT_FALSE(current_test, preemptible());
 145        krph_val = (rand1 / div_factor);
 146        return 0;
 147}
 148
 149static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 150{
 151        unsigned long ret = regs_return_value(regs);
 152
 153        KUNIT_EXPECT_FALSE(current_test, preemptible());
 154        KUNIT_EXPECT_EQ(current_test, ret, rand1 / div_factor);
 155        KUNIT_EXPECT_NE(current_test, krph_val, 0);
 156        krph_val = rand1;
 157        return 0;
 158}
 159
 160static struct kretprobe rp = {
 161        .handler        = return_handler,
 162        .entry_handler  = entry_handler,
 163        .kp.symbol_name = "kprobe_target"
 164};
 165
 166static void test_kretprobe(struct kunit *test)
 167{
 168        current_test = test;
 169        KUNIT_EXPECT_EQ(test, 0, register_kretprobe(&rp));
 170        target(rand1);
 171        unregister_kretprobe(&rp);
 172        KUNIT_EXPECT_EQ(test, krph_val, rand1);
 173}
 174
 175static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
 176{
 177        unsigned long ret = regs_return_value(regs);
 178
 179        KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor) + 1);
 180        KUNIT_EXPECT_NE(current_test, krph_val, 0);
 181        krph_val = rand1;
 182        return 0;
 183}
 184
 185static struct kretprobe rp2 = {
 186        .handler        = return_handler2,
 187        .entry_handler  = entry_handler,
 188        .kp.symbol_name = "kprobe_target2"
 189};
 190
 191static void test_kretprobes(struct kunit *test)
 192{
 193        struct kretprobe *rps[2] = {&rp, &rp2};
 194
 195        current_test = test;
 196        /* addr and flags should be cleard for reusing kprobe. */
 197        rp.kp.addr = NULL;
 198        rp.kp.flags = 0;
 199        KUNIT_EXPECT_EQ(test, 0, register_kretprobes(rps, 2));
 200
 201        krph_val = 0;
 202        target(rand1);
 203        KUNIT_EXPECT_EQ(test, krph_val, rand1);
 204
 205        krph_val = 0;
 206        target2(rand1);
 207        KUNIT_EXPECT_EQ(test, krph_val, rand1);
 208        unregister_kretprobes(rps, 2);
 209}
 210
 211#ifdef CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
 212#define STACK_BUF_SIZE 16
 213static unsigned long stack_buf[STACK_BUF_SIZE];
 214
 215static int stacktrace_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 216{
 217        unsigned long retval = regs_return_value(regs);
 218        int i, ret;
 219
 220        KUNIT_EXPECT_FALSE(current_test, preemptible());
 221        KUNIT_EXPECT_EQ(current_test, retval, target_return_address[1]);
 222
 223        /*
 224         * Test stacktrace inside the kretprobe handler, this will involves
 225         * kretprobe trampoline, but must include correct return address
 226         * of the target function.
 227         */
 228        ret = stack_trace_save(stack_buf, STACK_BUF_SIZE, 0);
 229        KUNIT_EXPECT_NE(current_test, ret, 0);
 230
 231        for (i = 0; i < ret; i++) {
 232                if (stack_buf[i] == target_return_address[1])
 233                        break;
 234        }
 235        KUNIT_EXPECT_NE(current_test, i, ret);
 236
 237#if !IS_MODULE(CONFIG_KPROBES_SANITY_TEST)
 238        /*
 239         * Test stacktrace from pt_regs at the return address. Thus the stack
 240         * trace must start from the target return address.
 241         */
 242        ret = stack_trace_save_regs(regs, stack_buf, STACK_BUF_SIZE, 0);
 243        KUNIT_EXPECT_NE(current_test, ret, 0);
 244        KUNIT_EXPECT_EQ(current_test, stack_buf[0], target_return_address[1]);
 245#endif
 246
 247        return 0;
 248}
 249
 250static struct kretprobe rp3 = {
 251        .handler        = stacktrace_return_handler,
 252        .kp.symbol_name = "kprobe_stacktrace_target"
 253};
 254
 255static void test_stacktrace_on_kretprobe(struct kunit *test)
 256{
 257        unsigned long myretaddr = (unsigned long)__builtin_return_address(0);
 258
 259        current_test = test;
 260        rp3.kp.addr = NULL;
 261        rp3.kp.flags = 0;
 262
 263        /*
 264         * Run the stacktrace_driver() to record correct return address in
 265         * stacktrace_target() and ensure stacktrace_driver() call is not
 266         * inlined by checking the return address of stacktrace_driver()
 267         * and the return address of this function is different.
 268         */
 269        KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
 270
 271        KUNIT_ASSERT_EQ(test, 0, register_kretprobe(&rp3));
 272        KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
 273        unregister_kretprobe(&rp3);
 274}
 275
 276static int stacktrace_internal_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 277{
 278        unsigned long retval = regs_return_value(regs);
 279        int i, ret;
 280
 281        KUNIT_EXPECT_FALSE(current_test, preemptible());
 282        KUNIT_EXPECT_EQ(current_test, retval, target_return_address[0]);
 283
 284        /*
 285         * Test stacktrace inside the kretprobe handler for nested case.
 286         * The unwinder will find the kretprobe_trampoline address on the
 287         * return address, and kretprobe must solve that.
 288         */
 289        ret = stack_trace_save(stack_buf, STACK_BUF_SIZE, 0);
 290        KUNIT_EXPECT_NE(current_test, ret, 0);
 291
 292        for (i = 0; i < ret - 1; i++) {
 293                if (stack_buf[i] == target_return_address[0]) {
 294                        KUNIT_EXPECT_EQ(current_test, stack_buf[i + 1], target_return_address[1]);
 295                        break;
 296                }
 297        }
 298        KUNIT_EXPECT_NE(current_test, i, ret);
 299
 300#if !IS_MODULE(CONFIG_KPROBES_SANITY_TEST)
 301        /* Ditto for the regs version. */
 302        ret = stack_trace_save_regs(regs, stack_buf, STACK_BUF_SIZE, 0);
 303        KUNIT_EXPECT_NE(current_test, ret, 0);
 304        KUNIT_EXPECT_EQ(current_test, stack_buf[0], target_return_address[0]);
 305        KUNIT_EXPECT_EQ(current_test, stack_buf[1], target_return_address[1]);
 306#endif
 307
 308        return 0;
 309}
 310
 311static struct kretprobe rp4 = {
 312        .handler        = stacktrace_internal_return_handler,
 313        .kp.symbol_name = "kprobe_stacktrace_internal_target"
 314};
 315
 316static void test_stacktrace_on_nested_kretprobe(struct kunit *test)
 317{
 318        unsigned long myretaddr = (unsigned long)__builtin_return_address(0);
 319        struct kretprobe *rps[2] = {&rp3, &rp4};
 320
 321        current_test = test;
 322        rp3.kp.addr = NULL;
 323        rp3.kp.flags = 0;
 324
 325        //KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
 326
 327        KUNIT_ASSERT_EQ(test, 0, register_kretprobes(rps, 2));
 328        KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
 329        unregister_kretprobes(rps, 2);
 330}
 331#endif /* CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE */
 332
 333#endif /* CONFIG_KRETPROBES */
 334
 335static int kprobes_test_init(struct kunit *test)
 336{
 337        target = kprobe_target;
 338        target2 = kprobe_target2;
 339        stacktrace_target = kprobe_stacktrace_target;
 340        internal_target = kprobe_stacktrace_internal_target;
 341        stacktrace_driver = kprobe_stacktrace_driver;
 342
 343        do {
 344                rand1 = prandom_u32();
 345        } while (rand1 <= div_factor);
 346        return 0;
 347}
 348
 349static struct kunit_case kprobes_testcases[] = {
 350        KUNIT_CASE(test_kprobe),
 351        KUNIT_CASE(test_kprobes),
 352#ifdef CONFIG_KRETPROBES
 353        KUNIT_CASE(test_kretprobe),
 354        KUNIT_CASE(test_kretprobes),
 355#ifdef CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
 356        KUNIT_CASE(test_stacktrace_on_kretprobe),
 357        KUNIT_CASE(test_stacktrace_on_nested_kretprobe),
 358#endif
 359#endif
 360        {}
 361};
 362
 363static struct kunit_suite kprobes_test_suite = {
 364        .name = "kprobes_test",
 365        .init = kprobes_test_init,
 366        .test_cases = kprobes_testcases,
 367};
 368
 369kunit_test_suites(&kprobes_test_suite);
 370
 371MODULE_LICENSE("GPL");
 372