diff options
author | Vyacheslav Cherkashin <v.cherkashin@samsung.com> | 2015-08-24 19:00:20 +0300 |
---|---|---|
committer | Dmitry Kovalenko <d.kovalenko@samsung.com> | 2015-08-27 23:23:03 -0700 |
commit | ee910feead1ca57f9b39949c64fc5573664ef573 (patch) | |
tree | 6bdf5f46c4da749411a252bd8833242a2aae9ab7 | |
parent | 2660ab3be63007ee996c9b40f1ff96599ffd363b (diff) | |
download | swap-modules-ee910feead1ca57f9b39949c64fc5573664ef573.tar.gz swap-modules-ee910feead1ca57f9b39949c64fc5573664ef573.tar.bz2 swap-modules-ee910feead1ca57f9b39949c64fc5573664ef573.zip |
[FIX] Flush kretprobe instances after last put_task
Remove rp_inst from kretprobe_inst_table when task has died
Change-Id: I97e8b7209e22f70c5c8ff3afc55704aa3ddfa87e
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
-rw-r--r-- | kprobe/swap_kprobes.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/kprobe/swap_kprobes.c b/kprobe/swap_kprobes.c index d080dd5b..ece1f7f8 100644 --- a/kprobe/swap_kprobes.c +++ b/kprobe/swap_kprobes.c @@ -1091,6 +1091,41 @@ static int swap_disarm_krp_inst(struct kretprobe_instance *ri) return retval; } +static void krp_inst_flush(struct task_struct *task) +{ + unsigned long flags; + struct kretprobe_instance *ri; + struct hlist_node *tmp; + struct hlist_head *head; + DECLARE_NODE_PTR_FOR_HLIST(node); + + spin_lock_irqsave(&kretprobe_lock, flags); + head = kretprobe_inst_table_head(task); + swap_hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task == task) { + printk("task[%u %u %s]: flush krp_inst, ret_addr=%p\n", + task->tgid, task->pid, task->comm, + ri->ret_addr); + recycle_rp_inst(ri); + } + } + spin_unlock_irqrestore(&kretprobe_lock, flags); +} + +static int put_task_handler(struct kprobe *p, struct pt_regs *regs) +{ + struct task_struct *t = (struct task_struct *)swap_get_karg(regs, 0); + + /* task has died */ + krp_inst_flush(t); + + return 0; +} + +static struct kprobe put_task_kp = { + .pre_handler = put_task_handler, +}; + static int init_module_deps(void) { int ret; @@ -1131,6 +1166,11 @@ static int once(void) if (module_alloc == NULL) goto not_found; + sym = "__put_task_struct"; + put_task_kp.addr = (void *)swap_ksyms(sym); + if (put_task_kp.addr == NULL) + goto not_found; + ret = init_module_deps(); if (ret) return ret; @@ -1153,14 +1193,27 @@ not_found: static int init_kprobes(void) { + int ret; + init_sm(); atomic_set(&kprobe_count, 0); - return swap_arch_init_kprobes(); + ret = swap_arch_init_kprobes(); + if (ret) + return ret; + + ret = swap_register_kprobe(&put_task_kp); + if (ret) { + swap_arch_exit_kprobes(); + return ret; + } + + return 0; } static void exit_kprobes(void) { + swap_unregister_kprobe(&put_task_kp); swap_arch_exit_kprobes(); exit_sm(); } |