Commit dc49e344 authored by Satoshi Oshima's avatar Satoshi Oshima Committed by Linus Torvalds

[PATCH] kprobes: bad manipulation of 2 byte opcode on x86_64

Problem:

If we put a probe onto a callq instruction and the probe is executed,
kernel panic of Bad RIP value occurs.

Root cause:

If resume_execution() found 0xff at first byte of p->ainsn.insn, it must
check the _second_ byte.  But current resume_execution check _first_ byte
again.

I changed it checks second byte of p->ainsn.insn.

Kprobes on i386 don't have this problem, because the implementation is a
little bit different from x86_64.

Cc: Andi Kleen <ak@muc.de>
Signed-off-by: default avatarSatoshi Oshima <soshima@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent be0d03f1
...@@ -514,13 +514,13 @@ static void __kprobes resume_execution(struct kprobe *p, ...@@ -514,13 +514,13 @@ static void __kprobes resume_execution(struct kprobe *p,
*tos = orig_rip + (*tos - copy_rip); *tos = orig_rip + (*tos - copy_rip);
break; break;
case 0xff: case 0xff:
if ((*insn & 0x30) == 0x10) { if ((insn[1] & 0x30) == 0x10) {
/* call absolute, indirect */ /* call absolute, indirect */
/* Fix return addr; rip is correct. */ /* Fix return addr; rip is correct. */
next_rip = regs->rip; next_rip = regs->rip;
*tos = orig_rip + (*tos - copy_rip); *tos = orig_rip + (*tos - copy_rip);
} else if (((*insn & 0x31) == 0x20) || /* jmp near, absolute indirect */ } else if (((insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */
((*insn & 0x31) == 0x21)) { /* jmp far, absolute indirect */ ((insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */
/* rip is correct. */ /* rip is correct. */
next_rip = regs->rip; next_rip = regs->rip;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment