aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnanth N Mavinakayanahalli <ananth@in.ibm.com>2006-02-03 06:03:43 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-03 11:32:00 -0500
commit278ff9537030bbb292b33504f5e1f6e0126793eb (patch)
tree0087828bdf4d9a4fb57c9bcafd068ff058b39797
parente65cefe87beda627c0bfba39b387ee4bffedc93c (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>
-rw-r--r--kernel/kprobes.c2
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
642static int __init init_kprobes(void) 642static int __init init_kprobes(void)