From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760302AbbA3Pns (ORCPT ); Fri, 30 Jan 2015 10:43:48 -0500 Received: from cantor2.suse.de ([195.135.220.15]:48589 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752604AbbA3Pnr (ORCPT ); Fri, 30 Jan 2015 10:43:47 -0500 From: Petr Mladek To: Masami Hiramatsu , "David S. Miller" , Anil S Keshavamurthy , Ananth N Mavinakayanahalli , Frederic Weisbecker Cc: Steven Rostedt , Jiri Kosina , linux-kernel@vger.kernel.org, Petr Mladek Subject: [PATCH] kprobes/x86: Use the current code when modified by Kprobes using ftrace Date: Fri, 30 Jan 2015 16:45:00 +0100 Message-Id: <1422632700-4342-1-git-send-email-pmladek@suse.cz> X-Mailer: git-send-email 1.8.5.6 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org can_probe() checks if the given address points to the beginning of an instruction. It analyzes all the instructions from the beginning of the function until the given address. The code might be modified by another Kprobe. In this case, the current code is read into a buffer, int3 breakpoint is replaced by the saved opcode in the buffer, and can_probe() analyzes the buffer instead. There is a bug that __recover_probed_insn() tries to restore the original code even for Kprobes using the ftrace framework. But in this case, the opcode is not stored. See the difference between arch_prepare_kprobe() and arch_prepare_kprobe_ftrace(). The opcode is stored by arch_copy_kprobe() only from arch_prepare_kprobe(). This patch makes Kprobe to use the current code when it is modified by ftrace. It is not the original one but it is a valid instruction of the same length. Therefore it is perfectly fine for the check. Note that I found this problem when playing with Kprobes. I did it on x86_64 with gcc-4.8.3 that supported -mfentry. I modified samples/kprobes/kprobe_example.c and added offset 5 to put the probe right after the fentry area: --- cut --- static struct kprobe kp = { .symbol_name = "do_fork", + .offset = 5, }; --- cut --- Then I was able to load kprobe_example before jprobe_example but not the other way around: $> modprobe jprobe_example $> modprobe kprobe_example modprobe: ERROR: could not insert 'kprobe_example': Invalid or incomplete multibyte or wide character It did not make much sense and debugging pointed to the bug described above. Signed-off-by: Petr Mladek --- arch/x86/kernel/kprobes/core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 98f654d466e5..ef321caae3ba 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -225,8 +225,14 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) struct kprobe *kp; kp = get_kprobe((void *)addr); - /* There is no probe, return original address */ - if (!kp) + /* + * Use the current code if it is not modified by Kprobe + * or when the Kprobe is using ftrace. In the second case + * we do not have any information about the original code + * but it is not a problem. Ftrace has put there a valid + * instruction of the same length. + */ + if (!kp || kprobe_ftrace(kp)) return addr; /* -- 1.8.5.6