2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * Copyright (C) Samsung Electronics, 2016
18 * 2016 Vyacheslav Cherkashin <v.cherkashin@samsung.com>
23 #include <linux/slab.h>
24 #include <linux/delay.h>
25 #include <linux/module.h>
26 #include <linux/kthread.h>
27 #include <kprobe/swap_kprobes.h>
28 #include "kp_module.h"
31 static struct task_struct *cur_task;
34 static struct kprobe *kp_create(char *name,
35 int (*pre_h)(struct kprobe *, struct pt_regs *))
39 p = kzalloc(sizeof(*p), GFP_KERNEL);
41 p->symbol_name = name;
42 p->pre_handler = pre_h;
48 static void kp_free(struct kprobe *p)
50 memset(p, 0x10, sizeof(*p));
53 #define kp_reg(ptr, name, handler) \
55 ptr = kp_create(name, handler); \
56 swap_register_kprobe(ptr); \
59 #define kp_unreg(ptr) \
61 swap_unregister_kprobe(ptr); \
67 noinline char *my_kstrdup(const char *s, gfp_t gfp)
69 return kstrdup(s, gfp);
72 noinline void my_kfree(const void *data)
81 ******************************************************************************
83 ******************************************************************************
85 static int kstrdup_cnt;
88 static struct kprobe *kp_kstrdup;
89 static int kstrdup_h(struct kprobe *kp, struct pt_regs *regs)
93 str = my_kstrdup("from_kfree_h", GFP_ATOMIC);
101 static struct kprobe *kp_kfree;
102 static int kfree_h(struct kprobe *kp, struct pt_regs *regs)
109 static void run_test_recursion(void)
113 str = my_kstrdup("test_string_0", GFP_KERNEL);
116 str = my_kstrdup("test_string_1", GFP_KERNEL);
120 static void do_test_recursion(void)
122 kp_reg(kp_kfree, "my_kfree", kfree_h);
123 kp_reg(kp_kstrdup, "my_kstrdup", kstrdup_h);
125 run_test_recursion();
127 kp_unreg(kp_kstrdup);
132 static void test_recursion(void)
134 olog("Recursion:\n");
141 if (kstrdup_cnt == 2 && kfree_cnt == 2) {
144 olog(" ERROR: kstrdup_cnt=%d kfree_cnt=%d\n",
145 kstrdup_cnt, kfree_cnt);
153 ******************************************************************************
154 * recursion and multiple handlers (Aggregate probe) *
155 ******************************************************************************
157 static int kfree2_cnt;
159 static struct kprobe *kp_kfree2;
160 static int kfree2_h(struct kprobe *kp, struct pt_regs *regs)
162 if (current != cur_task || in_interrupt())
169 static void pre_test_recursion_and_mh(void)
176 static void post_test_recursion_and_mh(void)
178 if (kstrdup_cnt == 2 && kfree_cnt == 2 && kfree2_cnt == 2) {
181 olog(" ERROR: kstrdup_cnt=%d kfree_cnt=%d kfree2_cnt=%d\n",
182 kstrdup_cnt, kfree_cnt, kfree2_cnt);
186 static void test_recursion_and_multiple_handlers(void)
188 olog("Recursion and multiple handlers:\n");
190 pre_test_recursion_and_mh();
192 kp_reg(kp_kfree2, "my_kfree", kfree2_h);
196 post_test_recursion_and_mh();
199 static void test_recursion_and_multiple_handlers2(void)
201 olog("Recursion and multiple handlers [II]:\n");
203 pre_test_recursion_and_mh();
205 kp_reg(kp_kfree, "my_kfree", kfree_h);
206 kp_reg(kp_kstrdup, "my_kstrdup", kstrdup_h);
207 kp_reg(kp_kfree2, "my_kfree", kfree2_h);
209 run_test_recursion();
211 kp_unreg(kp_kstrdup);
215 post_test_recursion_and_mh();
222 ******************************************************************************
223 * swap_unregister_kprobe(), sync *
224 ******************************************************************************
227 static const char task_name[] = "my_task";
229 static int is_my_task(void)
231 return !strcmp(task_name, current->comm);
234 static int find_module_cnt;
236 static struct kprobe *kp_find_module;
237 static int find_module_h(struct kprobe *kp, struct pt_regs *regs)
253 static int kthread_my_fn(void *data)
255 find_module("o_lo_lo");
256 find_module("o_lo_lo");
258 while (!kthread_should_stop()) {
259 set_current_state(TASK_INTERRUPTIBLE);
267 static void do_test_sync_unreg(unsigned int ms)
269 struct task_struct *task;
271 kp_reg(kp_find_module, "find_module", find_module_h);
273 task = kthread_run(kthread_my_fn, NULL, task_name);
275 olog("ERROR: kthread_run()\n");
279 /* waiting for kthread_my_fn() call */
282 kp_unreg(kp_find_module);
287 static void test_sync_unreg(void)
293 do_test_sync_unreg(200);
295 if (find_module_cnt == 2) {
298 olog(" ERROR: find_module_cnt=%d\n", find_module_cnt);
305 ******************************************************************************
306 * swap_unregister_kprobe(), sync and multiple handlers *
307 ******************************************************************************
309 static int find_module2_cnt;
311 static struct kprobe *kp_find_module2;
312 static int find_module2_h(struct kprobe *kp, struct pt_regs *regs)
326 static void pre_test_sync_unreg_and_mh(void)
329 find_module2_cnt = 0;
332 static void post_test_sync_unreg_and_mh(int cnt, int cnt2)
334 if (find_module_cnt == cnt && find_module2_cnt == cnt2) {
337 olog(" ERROR: find_module_cnt=%d find_module2_cnt=%d\n",
338 find_module_cnt, find_module2_cnt);
342 static void do_test_sync_unreg_and_mh(unsigned int ms)
344 struct task_struct *task;
346 kp_reg(kp_find_module, "find_module", find_module_h);
347 kp_reg(kp_find_module2, "find_module", find_module2_h);
349 task = kthread_run(kthread_my_fn, NULL, task_name);
351 olog("ERROR: kthread_run()\n");
355 /* waiting for kthread_my_fn() call */
358 kp_unreg(kp_find_module2);
359 kp_unreg(kp_find_module);
364 static void test_sync_unreg_and_multiple_handlers(void)
366 olog("Unreg kp and multiple handlers:\n");
368 pre_test_sync_unreg_and_mh();
370 do_test_sync_unreg_and_mh(700);
372 post_test_sync_unreg_and_mh(2, 2);
375 static void do_test_sync_unreg_and_mh2(unsigned int ms)
377 struct task_struct *task;
379 kp_reg(kp_find_module, "find_module", find_module_h);
380 kp_reg(kp_find_module2, "find_module", find_module2_h);
382 task = kthread_run(kthread_my_fn, NULL, task_name);
384 olog("ERROR: kthread_run()\n");
388 /* waiting for kthread_my_fn() call */
391 kp_unreg(kp_find_module);
392 kp_unreg(kp_find_module2);
397 static void test_sync_unreg_and_multiple_handlers2(void)
399 olog("Unreg kp and multiple handlers [II]:\n");
401 pre_test_sync_unreg_and_mh();
403 do_test_sync_unreg_and_mh2(700);
405 post_test_sync_unreg_and_mh(2, 2);
408 int kp_tests_run(void)
413 test_recursion_and_multiple_handlers();
414 test_recursion_and_multiple_handlers2();
418 test_sync_unreg_and_multiple_handlers();
419 test_sync_unreg_and_multiple_handlers2();