From: Satoshi Oshima Date: Sat, 20 May 2006 22:00:21 +0000 (-0700) Subject: [PATCH] kprobes: bad manipulation of 2 byte opcode on x86_64 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=dc49e3445aa703eb7fd33c7ddb7e4a7bbcf06d30;p=GitHub%2FLineageOS%2Fandroid_kernel_samsung_universal7580.git [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 --- 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; }