Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933178AbbG1KJf (ORCPT ); Tue, 28 Jul 2015 06:09:35 -0400 Received: from mail-wi0-f173.google.com ([209.85.212.173]:38109 "EHLO mail-wi0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932554AbbG1Jpb (ORCPT ); Tue, 28 Jul 2015 05:45:31 -0400 From: Jiri Slaby To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Eugene Shatokhin , Masami Hiramatsu , Ingo Molnar , Jiri Slaby Subject: [PATCH 3.12 065/124] kprobes/x86: Return correct length in __copy_instruction() Date: Tue, 28 Jul 2015 11:43:19 +0200 Message-Id: X-Mailer: git-send-email 2.4.6 In-Reply-To: <90d8a5681e4a9e320611b422f0ed012e148c2bca.1438076484.git.jslaby@suse.cz> References: <90d8a5681e4a9e320611b422f0ed012e148c2bca.1438076484.git.jslaby@suse.cz> In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2208 Lines: 66 From: Eugene Shatokhin 3.12-stable review patch. If anyone has any objections, please let me know. =============== commit c80e5c0c23ce2282476fdc64c4b5e3d3a40723fd upstream. On x86-64, __copy_instruction() always returns 0 (error) if the instruction uses %rip-relative addressing. This is because kernel_insn_init() is called the second time for 'insn' instance in such cases and sets all its fields to 0. Because of this, trying to place a kprobe on such instruction will fail, register_kprobe() will return -EINVAL. This patch fixes the problem. Signed-off-by: Eugene Shatokhin Signed-off-by: Masami Hiramatsu Link: http://lkml.kernel.org/r/20150317100918.28349.94654.stgit@localhost.localdomain Signed-off-by: Ingo Molnar Signed-off-by: Jiri Slaby --- arch/x86/kernel/kprobes/core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index a1f5b1866cbe..490fee15fea5 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -326,13 +326,16 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src) { struct insn insn; kprobe_opcode_t buf[MAX_INSN_SIZE]; + int length; kernel_insn_init(&insn, (void *)recover_probed_instruction(buf, (unsigned long)src)); insn_get_length(&insn); + length = insn.length; + /* Another subsystem puts a breakpoint, failed to recover */ if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) return 0; - memcpy(dest, insn.kaddr, insn.length); + memcpy(dest, insn.kaddr, length); #ifdef CONFIG_X86_64 if (insn_rip_relative(&insn)) { @@ -362,7 +365,7 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src) *(s32 *) disp = (s32) newdisp; } #endif - return insn.length; + return length; } static int __kprobes arch_copy_kprobe(struct kprobe *p) -- 2.4.6 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/