aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2007-12-18 12:05:58 -0500
committerIngo Molnar <mingo@elte.hu>2007-12-18 12:05:58 -0500
commit29b6cd794e73eea7600541d06288a09861ffecb0 (patch)
tree7f915b756058acc89cf3e85b75dcce0ec60a9e12 /arch/x86/kernel
parentb4be625852618636a6b54908c4f9d90fb29dc549 (diff)
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>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/kprobes_32.c4
-rw-r--r--arch/x86/kernel/kprobes_64.c6
2 files changed, 3 insertions, 7 deletions
diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c
index d87a523070d1..3a020f79f82b 100644
--- a/arch/x86/kernel/kprobes_32.c
+++ b/arch/x86/kernel/kprobes_32.c
@@ -727,9 +727,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
727 727
728 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { 728 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
729 if (&regs->esp != kcb->jprobe_saved_esp) { 729 if (&regs->esp != kcb->jprobe_saved_esp) {
730 struct pt_regs *saved_regs = 730 struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
731 container_of(kcb->jprobe_saved_esp,
732 struct pt_regs, esp);
733 printk("current esp %p does not match saved esp %p\n", 731 printk("current esp %p does not match saved esp %p\n",
734 &regs->esp, kcb->jprobe_saved_esp); 732 &regs->esp, kcb->jprobe_saved_esp);
735 printk("Saved registers for jprobe %p\n", jp); 733 printk("Saved registers for jprobe %p\n", jp);
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c
index 0c467644589c..a575059fb420 100644
--- a/arch/x86/kernel/kprobes_64.c
+++ b/arch/x86/kernel/kprobes_64.c
@@ -716,10 +716,8 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
716 struct jprobe *jp = container_of(p, struct jprobe, kp); 716 struct jprobe *jp = container_of(p, struct jprobe, kp);
717 717
718 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { 718 if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
719 if ((long *)regs->rsp != kcb->jprobe_saved_rsp) { 719 if ((unsigned long *)regs->rsp != kcb->jprobe_saved_rsp) {
720 struct pt_regs *saved_regs = 720 struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
721 container_of(kcb->jprobe_saved_rsp,
722 struct pt_regs, rsp);
723 printk("current rsp %p does not match saved rsp %p\n", 721 printk("current rsp %p does not match saved rsp %p\n",
724 (long *)regs->rsp, kcb->jprobe_saved_rsp); 722 (long *)regs->rsp, kcb->jprobe_saved_rsp);
725 printk("Saved registers for jprobe %p\n", jp); 723 printk("Saved registers for jprobe %p\n", jp);