~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/lib/test_kprobes.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /lib/test_kprobes.c (Version linux-6.12-rc7) and /lib/test_kprobes.c (Version linux-6.7.12)


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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php