From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751565AbdB0QOc (ORCPT ); Mon, 27 Feb 2017 11:14:32 -0500 Received: from mail.kernel.org ([198.145.29.136]:58240 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751327AbdB0QO3 (ORCPT ); Mon, 27 Feb 2017 11:14:29 -0500 From: Masami Hiramatsu To: Peter Zijlstra Cc: Masami Hiramatsu , Borislav Petkov , linux-kernel@vger.kernel.org, Ingo Molnar , Thomas Gleixner Subject: [RFC PATCH 1/2] kprobes/x86: Use probe_kernel_read instead of memcpy Date: Tue, 28 Feb 2017 01:13:28 +0900 Message-Id: <148821199864.15765.12168945785697241451.stgit@devbox> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170224174827.GS6500@twins.programming.kicks-ass.net> References: <20170224174827.GS6500@twins.programming.kicks-ass.net> In-Reply-To: <148821192807.15765.16863626307263805313.stgit@devbox> References: <148821192807.15765.16863626307263805313.stgit@devbox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Use probe_kernel_read() for avoiding unexpected faults while copying kernel text in both of __recover_probed_insn() and __recover_optprobed_insn(). Signed-off-by: Masami Hiramatsu --- arch/x86/kernel/kprobes/core.c | 7 +++++-- arch/x86/kernel/kprobes/opt.c | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 6384eb7..34d3a52 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -264,7 +264,10 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) * Fortunately, we know that the original code is the ideal 5-byte * long NOP. */ - memcpy(buf, (void *)addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); + if (probe_kernel_read(buf, (void *)addr, + MAX_INSN_SIZE * sizeof(kprobe_opcode_t))) + return 0UL; + if (faddr) memcpy(buf, ideal_nops[NOP_ATOMIC5], 5); else @@ -276,7 +279,7 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) * Recover the probed instruction at addr for further analysis. * Caller must lock kprobes by kprobe_mutex, or disable preemption * for preventing to release referencing kprobes. - * Returns zero if the instruction can not get recovered. + * Returns zero if the instruction can not get recovered (or access failed). */ unsigned long recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr) { diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index 3d1bee9..06ddd0b 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c @@ -65,7 +65,10 @@ unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr) * overwritten by jump destination address. In this case, original * bytes must be recovered from op->optinsn.copied_insn buffer. */ - memcpy(buf, (void *)addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); + if (probe_kernel_read(buf, (void *)addr, + MAX_INSN_SIZE * sizeof(kprobe_opcode_t))) + return 0UL; + if (addr == (unsigned long)kp->addr) { buf[0] = kp->opcode; memcpy(buf + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE);