x86: jprobe bugfix

jprobe for x86-64 may cause kernel page fault when the jprobe_return()
is called from incorrect function.

- Use jprobe_saved_regs instead getting it from stack.
(Especially on x86-64, it may get incorrect data, because
pt_regs can not be get by using container_of(rsp))
- Change the type of stack pointer to unsigned long *.

Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by Masami Hiramatsu and committed by Ingo Molnar 29b6cd79 b4be6258

+5 -9
+1 -3
arch/x86/kernel/kprobes_32.c
··· 727 727 728 728 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { 729 729 if (&regs->esp != kcb->jprobe_saved_esp) { 730 - struct pt_regs *saved_regs = 731 - container_of(kcb->jprobe_saved_esp, 732 - struct pt_regs, esp); 730 + struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; 733 731 printk("current esp %p does not match saved esp %p\n", 734 732 &regs->esp, kcb->jprobe_saved_esp); 735 733 printk("Saved registers for jprobe %p\n", jp);
+2 -4
arch/x86/kernel/kprobes_64.c
··· 716 716 struct jprobe *jp = container_of(p, struct jprobe, kp); 717 717 718 718 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { 719 - if ((long *)regs->rsp != kcb->jprobe_saved_rsp) { 720 - struct pt_regs *saved_regs = 721 - container_of(kcb->jprobe_saved_rsp, 722 - struct pt_regs, rsp); 719 + if ((unsigned long *)regs->rsp != kcb->jprobe_saved_rsp) { 720 + struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; 723 721 printk("current rsp %p does not match saved rsp %p\n", 724 722 (long *)regs->rsp, kcb->jprobe_saved_rsp); 725 723 printk("Saved registers for jprobe %p\n", jp);
+1 -1
include/asm-x86/kprobes_32.h
··· 73 73 unsigned long kprobe_status; 74 74 unsigned long kprobe_old_eflags; 75 75 unsigned long kprobe_saved_eflags; 76 - long *jprobe_saved_esp; 76 + unsigned long *jprobe_saved_esp; 77 77 struct pt_regs jprobe_saved_regs; 78 78 kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; 79 79 struct prev_kprobe prev_kprobe;
+1 -1
include/asm-x86/kprobes_64.h
··· 66 66 unsigned long kprobe_status; 67 67 unsigned long kprobe_old_rflags; 68 68 unsigned long kprobe_saved_rflags; 69 - long *jprobe_saved_rsp; 69 + unsigned long *jprobe_saved_rsp; 70 70 struct pt_regs jprobe_saved_regs; 71 71 kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; 72 72 struct prev_kprobe prev_kprobe;