From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 34831 invoked by alias); 11 Jun 2016 14:07:03 -0000 Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org Received: (qmail 34730 invoked by uid 89); 11 Jun 2016 14:07:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=H*F:D*kernel.org, bugfix X-HELO: mail.kernel.org Received: from mail.kernel.org (HELO mail.kernel.org) (198.145.29.136) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sat, 11 Jun 2016 14:07:01 +0000 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A141A20154; Sat, 11 Jun 2016 14:06:58 +0000 (UTC) Received: from localhost.localdomain (NE2965lan1.rev.em-net.ne.jp [210.141.244.193]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 864FC20149; Sat, 11 Jun 2016 14:06:56 +0000 (UTC) From: Masami Hiramatsu To: Ingo Molnar Cc: Masami Hiramatsu , linux-kernel@vger.kernel.org, Peter Zijlstra , Ananth N Mavinakayanahalli , Thomas Gleixner , "H . Peter Anvin" , Andy Lutomirski , systemtap@sourceware.org, Steven Rostedt Subject: [PATCH tip/master] [BUGFIX] kprobes/x86: Fix to clear TF bit in fault-on-single-stepping Date: Sat, 11 Jun 2016 14:07:00 -0000 Message-Id: <20160611140648.25885.37482.stgit@devbox> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-SW-Source: 2016-q2/txt/msg00217.txt.bz2 Fix kprobe_fault_handler to clear TF (trap flag) bit of flags register in the case of fault fixup on single-stepping. If we put a kprobe on the instruction which can cause a page fault (e.g. actual mov instructions in copy_user_*), that fault happens on a single-stepping buffer. In this case, kprobes resets running instance so that the CPU can retry execution on the original ip address. However, current code forgets reset TF bit. Since this fault happens with TF bit set for enabling single-stepping, when it retries, it causes a debug exception and kprobes can not handle it because it already reset itself. On the most of x86-64 platform, it can be easily reproduced by using kprobe tracer. E.g. # cd /sys/kernel/debug/tracing # echo p copy_user_enhanced_fast_string+5 > kprobe_events # echo 1 > events/kprobes/enable And you'll see a kernel panic on do_debug(), since the debug trap is not handled by kprobes. To fix this problem, we just need to clear the TF bit when resetting running kprobe. Signed-off-by: Masami Hiramatsu --- arch/x86/kernel/kprobes/core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 38cf7a7..856df81 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -961,6 +961,13 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr) * normal page fault. */ regs->ip = (unsigned long)cur->addr; + /* + * Trap flag has been set here because this fault happened + * where the single stepping will be done. So clear it with + * resetting current kprobe. + */ + regs->flags &= ~X86_EFLAGS_TF; + /* If the TF was set before the kprobe hit, don't touch it */ regs->flags |= kcb->kprobe_old_flags; if (kcb->kprobe_status == KPROBE_REENTER) restore_previous_kprobe(kcb);