diff options
author | Ananth N Mavinakayanahalli <ananth@in.ibm.com> | 2006-02-03 06:03:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-03 11:32:00 -0500 |
commit | 278ff9537030bbb292b33504f5e1f6e0126793eb (patch) | |
tree | 0087828bdf4d9a4fb57c9bcafd068ff058b39797 /kernel | |
parent | e65cefe87beda627c0bfba39b387ee4bffedc93c (diff) |
[PATCH] Kprobes: Fix deadlock in function-return probes
When two function-return probes are inserted on kfree()[1] and the second
on say, sys_link()[2], and later [2] is unregistered, we have a deadlock as
kfree is called with the kretprobe_lock held and the function-return probe
on kfree will also try to grab the same lock.
However, we can move the kfree() during unregistration to outside the
spinlock as we are sure that no instances from the free list will be used
after synchronized_sched() returns during the unregistration process.
Thanks to Masami Hiramatsu for spotting this.
Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/kprobes.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 95ad7f8db3d6..fef1af8a73ce 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -631,12 +631,12 @@ void __kprobes unregister_kretprobe(struct kretprobe *rp) | |||
631 | unregister_kprobe(&rp->kp); | 631 | unregister_kprobe(&rp->kp); |
632 | /* No race here */ | 632 | /* No race here */ |
633 | spin_lock_irqsave(&kretprobe_lock, flags); | 633 | spin_lock_irqsave(&kretprobe_lock, flags); |
634 | free_rp_inst(rp); | ||
635 | while ((ri = get_used_rp_inst(rp)) != NULL) { | 634 | while ((ri = get_used_rp_inst(rp)) != NULL) { |
636 | ri->rp = NULL; | 635 | ri->rp = NULL; |
637 | hlist_del(&ri->uflist); | 636 | hlist_del(&ri->uflist); |
638 | } | 637 | } |
639 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 638 | spin_unlock_irqrestore(&kretprobe_lock, flags); |
639 | free_rp_inst(rp); | ||
640 | } | 640 | } |
641 | 641 | ||
642 | static int __init init_kprobes(void) | 642 | static int __init init_kprobes(void) |