Skip to content

Commit 29b6cd7

Browse files
Masami HiramatsuIngo Molnar
authored andcommitted
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>
1 parent b4be625 commit 29b6cd7

File tree

4 files changed

+5
-9
lines changed

4 files changed

+5
-9
lines changed

arch/x86/kernel/kprobes_32.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -727,9 +727,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
727727

728728
if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
729729
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;
733731
printk("current esp %p does not match saved esp %p\n",
734732
&regs->esp, kcb->jprobe_saved_esp);
735733
printk("Saved registers for jprobe %p\n", jp);

arch/x86/kernel/kprobes_64.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -716,10 +716,8 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
716716
struct jprobe *jp = container_of(p, struct jprobe, kp);
717717

718718
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;
723721
printk("current rsp %p does not match saved rsp %p\n",
724722
(long *)regs->rsp, kcb->jprobe_saved_rsp);
725723
printk("Saved registers for jprobe %p\n", jp);

include/asm-x86/kprobes_32.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ struct kprobe_ctlblk {
7373
unsigned long kprobe_status;
7474
unsigned long kprobe_old_eflags;
7575
unsigned long kprobe_saved_eflags;
76-
long *jprobe_saved_esp;
76+
unsigned long *jprobe_saved_esp;
7777
struct pt_regs jprobe_saved_regs;
7878
kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
7979
struct prev_kprobe prev_kprobe;

include/asm-x86/kprobes_64.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct kprobe_ctlblk {
6666
unsigned long kprobe_status;
6767
unsigned long kprobe_old_rflags;
6868
unsigned long kprobe_saved_rflags;
69-
long *jprobe_saved_rsp;
69+
unsigned long *jprobe_saved_rsp;
7070
struct pt_regs jprobe_saved_regs;
7171
kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
7272
struct prev_kprobe prev_kprobe;

0 commit comments

Comments
 (0)