From dc49e3445aa703eb7fd33c7ddb7e4a7bbcf06d30 Mon Sep 17 00:00:00 2001 From: Satoshi Oshima Date: Sat, 20 May 2006 15:00:21 -0700 Subject: [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 Signed-off-by: Satoshi Oshima Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/kprobes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/x86_64/kernel') diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index 1eaa5dae617..fa1d19ca700 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -514,13 +514,13 @@ static void __kprobes resume_execution(struct kprobe *p, *tos = orig_rip + (*tos - copy_rip); break; case 0xff: - if ((*insn & 0x30) == 0x10) { + if ((insn[1] & 0x30) == 0x10) { /* call absolute, indirect */ /* Fix return addr; rip is correct. */ next_rip = regs->rip; *tos = orig_rip + (*tos - copy_rip); - } else if (((*insn & 0x31) == 0x20) || /* jmp near, absolute indirect */ - ((*insn & 0x31) == 0x21)) { /* jmp far, absolute indirect */ + } else if (((insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */ + ((insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */ /* rip is correct. */ next_rip = regs->rip; } -- cgit v1.2.3