diff options
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/kernel/kprobes.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index d04f0ab2ff40..ac241567e682 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c | |||
@@ -405,11 +405,12 @@ no_kprobe: | |||
405 | int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | 405 | int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) |
406 | { | 406 | { |
407 | struct kretprobe_instance *ri = NULL; | 407 | struct kretprobe_instance *ri = NULL; |
408 | struct hlist_head *head; | 408 | struct hlist_head *head, empty_rp; |
409 | struct hlist_node *node, *tmp; | 409 | struct hlist_node *node, *tmp; |
410 | unsigned long flags, orig_ret_address = 0; | 410 | unsigned long flags, orig_ret_address = 0; |
411 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; | 411 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; |
412 | 412 | ||
413 | INIT_HLIST_HEAD(&empty_rp); | ||
413 | spin_lock_irqsave(&kretprobe_lock, flags); | 414 | spin_lock_irqsave(&kretprobe_lock, flags); |
414 | head = kretprobe_inst_table_head(current); | 415 | head = kretprobe_inst_table_head(current); |
415 | 416 | ||
@@ -435,7 +436,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
435 | ri->rp->handler(ri, regs); | 436 | ri->rp->handler(ri, regs); |
436 | 437 | ||
437 | orig_ret_address = (unsigned long)ri->ret_addr; | 438 | orig_ret_address = (unsigned long)ri->ret_addr; |
438 | recycle_rp_inst(ri); | 439 | recycle_rp_inst(ri, &empty_rp); |
439 | 440 | ||
440 | if (orig_ret_address != trampoline_address) | 441 | if (orig_ret_address != trampoline_address) |
441 | /* | 442 | /* |
@@ -453,6 +454,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
453 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 454 | spin_unlock_irqrestore(&kretprobe_lock, flags); |
454 | preempt_enable_no_resched(); | 455 | preempt_enable_no_resched(); |
455 | 456 | ||
457 | hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { | ||
458 | hlist_del(&ri->hlist); | ||
459 | kfree(ri); | ||
460 | } | ||
456 | /* | 461 | /* |
457 | * By returning a non-zero value, we are telling | 462 | * By returning a non-zero value, we are telling |
458 | * kprobe_handler() that we don't want the post_handler | 463 | * kprobe_handler() that we don't want the post_handler |