Skip to content

Commit

Permalink
[PATCH] kretprobe: fix kretprobe-booster to save regs and set status
Browse files Browse the repository at this point in the history
There are two bugs in the kretprobe-booster.

1) It doesn't make room for gs registers.

2) It doesn't change status of the current kprobe.  This status will
   effect the fault handling.

This patch fixes these bugs and, additionally, saves skipped registers for
compatibility with the original kretprobe.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Masami Hiramatsu authored and Linus Torvalds committed Nov 9, 2006
1 parent 4b438a2 commit 8bdc052
Showing 1 changed file with 15 additions and 7 deletions.
22 changes: 15 additions & 7 deletions arch/i386/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,11 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
asm volatile ( ".global kretprobe_trampoline\n"
"kretprobe_trampoline: \n"
" pushf\n"
/* skip cs, eip, orig_eax, es, ds */
" subl $20, %esp\n"
/* skip cs, eip, orig_eax */
" subl $12, %esp\n"
" pushl %gs\n"
" pushl %ds\n"
" pushl %es\n"
" pushl %eax\n"
" pushl %ebp\n"
" pushl %edi\n"
Expand All @@ -373,19 +376,19 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
" movl %esp, %eax\n"
" call trampoline_handler\n"
/* move eflags to cs */
" movl 48(%esp), %edx\n"
" movl %edx, 44(%esp)\n"
" movl 52(%esp), %edx\n"
" movl %edx, 48(%esp)\n"
/* save true return address on eflags */
" movl %eax, 48(%esp)\n"
" movl %eax, 52(%esp)\n"
" popl %ebx\n"
" popl %ecx\n"
" popl %edx\n"
" popl %esi\n"
" popl %edi\n"
" popl %ebp\n"
" popl %eax\n"
/* skip eip, orig_eax, es, ds */
" addl $16, %esp\n"
/* skip eip, orig_eax, es, ds, gs */
" addl $20, %esp\n"
" popf\n"
" ret\n");
}
Expand All @@ -404,6 +407,10 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
INIT_HLIST_HEAD(&empty_rp);
spin_lock_irqsave(&kretprobe_lock, flags);
head = kretprobe_inst_table_head(current);
/* fixup registers */
regs->xcs = __KERNEL_CS;
regs->eip = trampoline_address;
regs->orig_eax = 0xffffffff;

/*
* It is possible to have multiple instances associated with a given
Expand All @@ -425,6 +432,7 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)

if (ri->rp && ri->rp->handler){
__get_cpu_var(current_kprobe) = &ri->rp->kp;
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
ri->rp->handler(ri, regs);
__get_cpu_var(current_kprobe) = NULL;
}
Expand Down

0 comments on commit 8bdc052

Please sign in to comment.