aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/kprobes.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 5beda378cc75..fde5a16a2913 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -462,9 +462,16 @@ int __kprobes register_kprobe(struct kprobe *p)
462 int ret = 0; 462 int ret = 0;
463 unsigned long flags = 0; 463 unsigned long flags = 0;
464 struct kprobe *old_p; 464 struct kprobe *old_p;
465 struct module *mod;
466
467 if ((!kernel_text_address((unsigned long) p->addr)) ||
468 in_kprobes_functions((unsigned long) p->addr))
469 return -EINVAL;
470
471 if ((mod = module_text_address((unsigned long) p->addr)) &&
472 (unlikely(!try_module_get(mod))))
473 return -EINVAL;
465 474
466 if ((ret = in_kprobes_functions((unsigned long) p->addr)) != 0)
467 return ret;
468 if ((ret = arch_prepare_kprobe(p)) != 0) 475 if ((ret = arch_prepare_kprobe(p)) != 0)
469 goto rm_kprobe; 476 goto rm_kprobe;
470 477
@@ -488,6 +495,8 @@ out:
488rm_kprobe: 495rm_kprobe:
489 if (ret == -EEXIST) 496 if (ret == -EEXIST)
490 arch_remove_kprobe(p); 497 arch_remove_kprobe(p);
498 if (ret && mod)
499 module_put(mod);
491 return ret; 500 return ret;
492} 501}
493 502
@@ -495,6 +504,7 @@ void __kprobes unregister_kprobe(struct kprobe *p)
495{ 504{
496 unsigned long flags; 505 unsigned long flags;
497 struct kprobe *old_p; 506 struct kprobe *old_p;
507 struct module *mod;
498 508
499 spin_lock_irqsave(&kprobe_lock, flags); 509 spin_lock_irqsave(&kprobe_lock, flags);
500 old_p = get_kprobe(p->addr); 510 old_p = get_kprobe(p->addr);
@@ -506,6 +516,10 @@ void __kprobes unregister_kprobe(struct kprobe *p)
506 cleanup_kprobe(p, flags); 516 cleanup_kprobe(p, flags);
507 517
508 synchronize_sched(); 518 synchronize_sched();
519
520 if ((mod = module_text_address((unsigned long)p->addr)))
521 module_put(mod);
522
509 if (old_p->pre_handler == aggr_pre_handler && 523 if (old_p->pre_handler == aggr_pre_handler &&
510 list_empty(&old_p->list)) 524 list_empty(&old_p->list))
511 kfree(old_p); 525 kfree(old_p);