From 600af57f586542f0808f635307cdfbf020f69fd4 Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Wed, 20 Feb 2013 18:56:46 +0400 Subject: [PATCH] remove uretprobes in children task --- driver/us_proc_inst.c | 1 + kprobe/dbi_kprobes.c | 29 ++++++++++++++++++++++++++++- kprobe/dbi_kprobes.h | 1 + kprobe/dbi_uprobes.c | 8 ++++---- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/driver/us_proc_inst.c b/driver/us_proc_inst.c index 5e16646..6ca87b9 100644 --- a/driver/us_proc_inst.c +++ b/driver/us_proc_inst.c @@ -1090,6 +1090,7 @@ EXPORT_SYMBOL_GPL(mm_release_probe_pre_code); static void recover_child(struct task_struct *child_task, struct sspt_procs *procs) { uninstall_us_proc_probes(child_task, procs, US_DISARM); + dbi_disarm_urp_inst_for_task(current, child_task); } static void rm_uprobes_child(struct task_struct *new_task) diff --git a/kprobe/dbi_kprobes.c b/kprobe/dbi_kprobes.c index b59d29f..55410cc 100644 --- a/kprobe/dbi_kprobes.c +++ b/kprobe/dbi_kprobes.c @@ -329,6 +329,33 @@ void recycle_rp_inst (struct kretprobe_instance *ri) } } +int dbi_disarm_urp_inst(struct kretprobe_instance *ri, struct task_struct *rm_task); + +int dbi_disarm_urp_inst_for_task(struct task_struct *parent, struct task_struct *task) +{ + int i, ret; + unsigned long table_size, flags; + struct kretprobe_instance *ri; + struct hlist_node *node, *tmp; + struct hlist_head *head; + + table_size = (1 << KPROBE_HASH_BITS); + + spin_lock_irqsave(&kretprobe_lock, flags); + for (i = 0; i < table_size; ++i) { + head = &kretprobe_inst_table[i]; + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (parent == ri->task) { + dbi_disarm_urp_inst(ri, task); + } + } + } + spin_unlock_irqrestore(&kretprobe_lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(dbi_disarm_urp_inst_for_task); + struct hlist_head * kretprobe_inst_table_head (void *hash_key) { return &kretprobe_inst_table[hash_ptr (hash_key, KPROBE_HASH_BITS)]; @@ -834,7 +861,7 @@ static int dbi_disarm_krp_inst(struct kretprobe_instance *ri) task_cpu(ri->task), ri->task->comm, ri->task->tgid, ri->task->pid, (unsigned long)tramp, - (unsigned long)found, (unsigned long)ri->sp, found - ri->sp, + (unsigned long)found, (unsigned long)ri->sp, found - ri->sp, ri->rp ? ri->rp->kp.addr: NULL); *found = (unsigned long)ri->ret_addr; retval = 0; diff --git a/kprobe/dbi_kprobes.h b/kprobe/dbi_kprobes.h index 62bd82c..01cf0ef 100644 --- a/kprobe/dbi_kprobes.h +++ b/kprobe/dbi_kprobes.h @@ -262,6 +262,7 @@ struct kretprobe_instance *get_free_rp_inst_no_alloc (struct kretprobe *rp); void free_rp_inst (struct kretprobe *rp); void add_rp_inst (struct kretprobe_instance *ri); void recycle_rp_inst (struct kretprobe_instance *ri); +int dbi_disarm_urp_inst_for_task(struct task_struct *parent, struct task_struct *task); //void kretprobe_trampoline_holder (void); int trampoline_probe_handler (struct kprobe *p, struct pt_regs *regs); diff --git a/kprobe/dbi_uprobes.c b/kprobe/dbi_uprobes.c index 3937996..1f3209a 100644 --- a/kprobe/dbi_uprobes.c +++ b/kprobe/dbi_uprobes.c @@ -270,9 +270,9 @@ out: return ret; } -static int dbi_disarm_urp_inst(struct kretprobe_instance *ri) +int dbi_disarm_urp_inst(struct kretprobe_instance *ri, struct task_struct *rm_task) { - struct task_struct *task = ri->task; + struct task_struct *task = rm_task ? rm_task : ri->task; kprobe_opcode_t *tramp = (kprobe_opcode_t *)(ri->rp->kp.ainsn.insn + UPROBES_TRAMP_RET_BREAK_IDX); kprobe_opcode_t *stack = ri->sp - RETPROBE_STACK_DEPTH; @@ -328,9 +328,9 @@ void dbi_unregister_uretprobe(struct task_struct *task, struct kretprobe *rp, in spin_lock_irqsave (&kretprobe_lock, flags); while ((ri = get_used_rp_inst(rp)) != NULL) { - if (dbi_disarm_urp_inst(ri) != 0) + if (dbi_disarm_urp_inst(ri, NULL) != 0) /*panic*/printk("%s (%d/%d): cannot disarm urp instance (%08lx)\n", - ri->task->comm, ri->task->tgid, ri->task->pid, + ri->task->comm, ri->task->tgid, ri->task->pid, (unsigned long)rp->kp.addr); recycle_rp_inst(ri); } -- 2.7.4