From e62546ece6770151bfcc4d594eb18e51fb791793 Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Thu, 3 Apr 2014 10:51:06 +0400 Subject: [PATCH] [IMPROVE] unregister kretprobe top/bottom interface Change-Id: I313c49ee1b74ddf09e461ada43ce10962715ec00 Signed-off-by: Vyacheslav Cherkashin --- kprobe/dbi_kprobes.c | 49 +++++++++++++++++++++++++++++++++++-------------- kprobe/dbi_kprobes.h | 14 ++++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/kprobe/dbi_kprobes.c b/kprobe/dbi_kprobes.c index ce9fe4b..6a043a5 100644 --- a/kprobe/dbi_kprobes.c +++ b/kprobe/dbi_kprobes.c @@ -822,13 +822,11 @@ int dbi_register_kretprobe(struct kretprobe *rp) static int dbi_disarm_krp_inst(struct kretprobe_instance *ri); -static void dbi_unregister_kretprobe_top(struct kretprobe *rp) +static void dbi_disarm_krp(struct kretprobe *rp) { struct kretprobe_instance *ri; DECLARE_NODE_PTR_FOR_HLIST(node); - dbi_unregister_kprobe(&rp->kp); - swap_hlist_for_each_entry(ri, node, &rp->used_instances, uflist) { if (dbi_disarm_krp_inst(ri) != 0) { printk("%s (%d/%d): cannot disarm krp instance (%08lx)\n", @@ -838,7 +836,29 @@ static void dbi_unregister_kretprobe_top(struct kretprobe *rp) } } -static void dbi_unregister_kretprobe_bottom(struct kretprobe *rp) +void dbi_unregister_kretprobes_top(struct kretprobe **rps, size_t size, + int rp_disarm) +{ + unsigned long flags; + const size_t end = ((size_t) 0) - 1; + + spin_lock_irqsave(&kretprobe_lock, flags); + for (--size; size != end; --size) { + dbi_unregister_kprobe(&rps[size]->kp); + if (rp_disarm) + dbi_disarm_krp(rps[size]); + } + spin_unlock_irqrestore(&kretprobe_lock, flags); +} +EXPORT_SYMBOL_GPL(dbi_unregister_kretprobes_top); + +void dbi_unregister_kretprobe_top(struct kretprobe *rp, int rp_disarm) +{ + dbi_unregister_kretprobes_top(&rp, 1, rp_disarm); +} +EXPORT_SYMBOL_GPL(dbi_unregister_kretprobe_top); + +void dbi_unregister_kretprobe_bottom(struct kretprobe *rp) { unsigned long flags; struct kretprobe_instance *ri; @@ -855,24 +875,25 @@ static void dbi_unregister_kretprobe_bottom(struct kretprobe *rp) spin_unlock_irqrestore(&kretprobe_lock, flags); } +EXPORT_SYMBOL_GPL(dbi_unregister_kretprobe_bottom); -void dbi_unregister_kretprobes(struct kretprobe **rpp, size_t size) +void dbi_unregister_kretprobes_bottom(struct kretprobe **rps, size_t size) { - size_t i; - unsigned long flags; - - spin_lock_irqsave(&kretprobe_lock, flags); + const size_t end = ((size_t) 0) - 1; - for (i = 0; i < size; i++) - dbi_unregister_kretprobe_top(rpp[i]); + for (--size; size != end; --size) + dbi_unregister_kretprobe_bottom(rps[size]); +} +EXPORT_SYMBOL_GPL(dbi_unregister_kretprobes_bottom); - spin_unlock_irqrestore(&kretprobe_lock, flags); +void dbi_unregister_kretprobes(struct kretprobe **rpp, size_t size) +{ + dbi_unregister_kretprobes_top(rpp, size, 1); if (!in_atomic()) synchronize_sched(); - for (i = 0; i < size; i++) - dbi_unregister_kretprobe_bottom(rpp[i]); + dbi_unregister_kretprobes_bottom(rpp, size); } void dbi_unregister_kretprobe(struct kretprobe *rp) diff --git a/kprobe/dbi_kprobes.h b/kprobe/dbi_kprobes.h index 7c6a479..9e8b393 100644 --- a/kprobe/dbi_kprobes.h +++ b/kprobe/dbi_kprobes.h @@ -256,6 +256,20 @@ int dbi_register_kretprobe (struct kretprobe *rp); void dbi_unregister_kretprobe (struct kretprobe *rp); void dbi_unregister_kretprobes(struct kretprobe **rpp, size_t size); +/* + * use: + * dbi_unregister_kretprobe[s]_top(); + * synchronize_sched(); + * dbi_unregister_kretprobe[s]_bottom(); + * + * rp_disarm - indicates the need for restoration of the return address + */ +void dbi_unregister_kretprobe_top(struct kretprobe *rp, int rp_disarm); +void dbi_unregister_kretprobes_top(struct kretprobe **rps, size_t size, + int rp_disarm); +void dbi_unregister_kretprobe_bottom(struct kretprobe *rp); +void dbi_unregister_kretprobes_bottom(struct kretprobe **rps, size_t size); + void kretprobe_assert (struct kretprobe_instance *ri, unsigned long orig_ret_address, unsigned long trampoline_address); -- 2.7.4