From patchwork Fri Oct 8 12:29:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 12545261 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1DCEC433EF for ; Fri, 8 Oct 2021 12:39:58 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9D75660F93 for ; Fri, 8 Oct 2021 12:39:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 9D75660F93 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=jG29plJd4+Le3oNK+G+Wf6FG/+F3t/MwmlBQsJW8DP0=; b=Y7sfuY6jRhD0o6 2/fEwWQP2mzPlPjObyYXcmKBP8RZbfGjgmCZauq4tGfxOT9kcwqPXJefo4bqsxp0xn7JtzOZ02ADT NE8qxBueyZHGCsMH5UGVGcHRSK8GilzvprDp+thrpqX7OPHh9lQXD9Iis1TB7/DtbEUfyR8xPu+F5 OWiVSLMzc+3G5Rvrd1LOCHO6EyVibP77A4Vkf4n4ruBgI84ulQoEioiAW2nRY4lg52EJnO2MglnLm Yk3Ib3IgcPiGOEj4RSn0N/VdHK4GFtaa4jxhSdIVVw9u/69QdAZSK//rdSZ0Aop1Yu9EOPeKmWFdA TEzALplasbX5XLAYmeiw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mYp8F-002l5s-Vc; Fri, 08 Oct 2021 12:37:48 +0000 Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mYp0D-002iK2-Ag for linux-arm-kernel@lists.infradead.org; Fri, 08 Oct 2021 12:29:31 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id 4736260FD8; Fri, 8 Oct 2021 12:29:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1633696168; bh=8KEq6p7WetumdXoHhpIIywuWI4pHhMiVHABA49TNKEw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tlIth+cPvKMGPoy44bX7uS9Zx6f1dW4W7I7mMO4gM4knLY4ejOFezNcwFVtcfUuHl n8zueouGrKXoVLVaUBBgO8KMZrJlReZ+M9fEkJ/M7StH7rC+q0UAw/ZK23wZWLLtAW c6X0IHj8jmknLGNRGtp0ANBMNUKhYhRd7nFyMro4VChWk8vY73Jp6+xmG1ZZxY3k0e JxZcNZ/OxwtuzjHic1Ezg+8dyz+DrexuI+Xxtx0AE7rbAbEVcL36sa69genddR23Wd kl0PVrDHqfAAlF8ganiNSJ5t0BXATj2lqHP2wEIhZzkivXODaH/zRQ9ymdA4iBPrrY AbcdkYfzN89Ng== From: Masami Hiramatsu To: Steven Rostedt Cc: "Naveen N . Rao" , Ananth N Mavinakayanahalli , Ingo Molnar , linux-kernel@vger.kernel.org, mhiramat@kernel.org, Sven Schnelle , Catalin Marinas , Will Deacon , Russell King , Nathan Chancellor , Nick Desaulniers , linux-arm-kernel@lists.infradead.org Subject: [PATCH 8/8] ARM: Recover kretprobe modified return address in stacktrace Date: Fri, 8 Oct 2021 21:29:26 +0900 Message-Id: <163369616584.636038.13479045721903402698.stgit@devnote2> X-Mailer: git-send-email 2.25.1 In-Reply-To: <163369609308.636038.15295764725220907794.stgit@devnote2> References: <163369609308.636038.15295764725220907794.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211008_052929_448002_62B2F2A7 X-CRM114-Status: GOOD ( 16.37 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Since the kretprobe replaces the function return address with the kretprobe_trampoline on the stack, arm unwinder shows it instead of the correct return address. This finds the correct return address from the per-task kretprobe_instances list and verify it is in between the caller fp and callee fp. Note that this supports both GCC and clang if CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=n. For the ARM unwinder, this is still not working correctly. Signed-off-by: Masami Hiramatsu --- arch/arm/Kconfig | 1 + arch/arm/include/asm/stacktrace.h | 5 +++++ arch/arm/kernel/return_address.c | 2 ++ arch/arm/kernel/stacktrace.c | 8 ++++++++ 4 files changed, 16 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fc196421b2ce..bb4f1872967c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -3,6 +3,7 @@ config ARM bool default y select ARCH_32BIT_OFF_T + select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND select ARCH_HAS_BINFMT_FLAT select ARCH_HAS_DEBUG_VIRTUAL if MMU select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h index 2d76a2e29f05..3c23abe935f2 100644 --- a/arch/arm/include/asm/stacktrace.h +++ b/arch/arm/include/asm/stacktrace.h @@ -3,6 +3,7 @@ #define __ASM_STACKTRACE_H #include +#include struct stackframe { /* @@ -13,6 +14,8 @@ struct stackframe { unsigned long sp; unsigned long lr; unsigned long pc; + struct llist_node *kr_cur; + struct task_struct *tsk; }; static __always_inline @@ -22,6 +25,8 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame) frame->sp = regs->ARM_sp; frame->lr = regs->ARM_lr; frame->pc = regs->ARM_pc; + frame->kr_cur = NULL; + frame->tsk = current; } extern int unwind_frame(struct stackframe *frame); diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c index 7b42ac010fdf..6fea64d74ebc 100644 --- a/arch/arm/kernel/return_address.c +++ b/arch/arm/kernel/return_address.c @@ -42,6 +42,8 @@ void *return_address(unsigned int level) frame.sp = current_stack_pointer; frame.lr = (unsigned long)__builtin_return_address(0); frame.pc = (unsigned long)return_address; + frame.tsk = current; + frame.kr_cur = NULL; walk_stackframe(&frame, save_return_addr, &data); diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index db798eac7431..7022dda02b93 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include #include #include #include @@ -65,6 +66,9 @@ int notrace unwind_frame(struct stackframe *frame) frame->sp = *(unsigned long *)(fp - 8); frame->pc = *(unsigned long *)(fp - 4); #endif + if (is_kretprobe_trampoline(frame->pc)) + frame->pc = kretprobe_find_ret_addr(frame->tsk, + (void *)frame->fp, &frame->kr_cur); return 0; } @@ -156,6 +160,8 @@ static noinline void __save_stack_trace(struct task_struct *tsk, frame.lr = (unsigned long)__builtin_return_address(0); frame.pc = (unsigned long)__save_stack_trace; } + frame.kr_cur = NULL; + frame.tsk = tsk; walk_stackframe(&frame, save_trace, &data); } @@ -173,6 +179,8 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) frame.sp = regs->ARM_sp; frame.lr = regs->ARM_lr; frame.pc = regs->ARM_pc; + frame.kr_cur = NULL; + frame.tsk = current; walk_stackframe(&frame, save_trace, &data); }