Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp917955pxb; Fri, 15 Oct 2021 20:09:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxJTpmWtqUqNkr6y19EiJV6YDHJE2VFR8YLtJYRR8MjBNTVHwPdIjW/4A0l+SMViFlk5COh X-Received: by 2002:a17:902:ea0a:b0:13e:8b24:b94 with SMTP id s10-20020a170902ea0a00b0013e8b240b94mr14325313plg.45.1634353760275; Fri, 15 Oct 2021 20:09:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634353760; cv=none; d=google.com; s=arc-20160816; b=DbpgqnonBKJ3MgXSjL0iWhflcOVZBNJz3W4fWolvI4bHPDdEFtbYgeD9IgJi1e1N/Y fzbR78CcOShq8WQH47vhSdrky7HOEr8GeFiyZEk+KUSYRjaHYx3yaZVqBM4U3eqU4Kao ogUx1xItZ5Xgw0DP/k5C7FHMBgHX7Libu10UV1D7nRSrARlRvTCLir1sDIY3yucXS83n UQarH3gidQNpvfHQR5EBVxPDVGoMngT7pPIRF55ZUr3FNpICBH1YJbVJSX5kDZa2pLQc GoZadknA3/wpnxdR8bTciF1zP7gcQrbNKzmJP5mglMsqIv/n9sv9cjmpWdo+UIQODN+B 8sgw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=2xqDSpBi+BzMtIyLc0zAt31f4dgV0wcQBJZxb8JMKZ0=; b=pimlt/Ka7ik5JPCBrcPw68a4KUQG/y4va80BaIjCFAiVRYvs6R5BRgvtFNMY1GU02n HX2chDbKQrgRCzpLdnFwZQPC0cTgpLLP5pYF2w/V4aWccZ94t6spZfVkcNVKBCtXiEgB UqY4nJax40+0FHd5nF9RfSq/2vUBbXdjSnPdT0OyWt6czvZUbbSNUN3B1vrt2IH7tHH7 o9I4N5wzliqgUFF7LevJIklfmi/gvc5xKH8GlbrU/g+E69WlwXMCwIaFtlXw3UhTe0IH 6nYw6KNFQqHTHMpahVnULIQ2pRqLwBuG+RF19TA4FfLd1u+YV4xKnH9d+76PaT0rqf9K FiFQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=h0HJxPso; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e24si9403506pjr.129.2021.10.15.20.08.38; Fri, 15 Oct 2021 20:09:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=h0HJxPso; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239307AbhJOMyV (ORCPT + 99 others); Fri, 15 Oct 2021 08:54:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:53988 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235793AbhJOMyP (ORCPT ); Fri, 15 Oct 2021 08:54:15 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id D0BE360230; Fri, 15 Oct 2021 12:52:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634302329; bh=6eQhPcwTPWL7PeCf0bKVrZpLNkk5pcOdMHPKs5Ym+g0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=h0HJxPsoPmofnkEevWSCquKWYTveY+4/knPL9GnpoTUYrLgtm9PCbQV3VLBihKAXU 90V8KNHFcWpAQHxPhFNz7FZsPGl9utoCpIIaXmLxz5PTFdc9ddu0BJT4vP4O/2f3xc nSnu1hJbSJSwkHoSfm5UVIN3GiXeNTKY3eXyDSOYeZVGM6Ov3PC3q7FJ8glFFq+OHF V8w+jqXnJ8HMw1d4Pqw191j7fHJSX9O7irtYBNvqAJ0WD7gpugeViu8dP1Thj+wVNy IbMwZtb1Aozkf9idA8lW0Wo6r0AddCvzNo1lLhRgcIAQ2i/Q8vWuSsJkCsp5Cbnx1U AujxEWst0a/aw== 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 09/10] ARM: Recover kretprobe modified return address in stacktrace Date: Fri, 15 Oct 2021 21:52:04 +0900 Message-Id: <163430232448.459050.59665093997557853.stgit@devnote2> X-Mailer: git-send-email 2.25.1 In-Reply-To: <163430224341.459050.2369208860773018092.stgit@devnote2> References: <163430224341.459050.2369208860773018092.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.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 --- Changes in v2: - Compile this code only when CONFIG_KRETPROBES=y --- arch/arm/Kconfig | 1 + arch/arm/include/asm/stacktrace.h | 9 +++++++++ arch/arm/kernel/return_address.c | 4 ++++ arch/arm/kernel/stacktrace.c | 14 ++++++++++++++ 4 files changed, 28 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..8f54f9ad8a9b 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,10 @@ struct stackframe { unsigned long sp; unsigned long lr; unsigned long pc; +#ifdef CONFIG_KRETPROBES + struct llist_node *kr_cur; + struct task_struct *tsk; +#endif }; static __always_inline @@ -22,6 +27,10 @@ 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; +#ifdef CONFIG_KRETPROBES + frame->kr_cur = NULL; + frame->tsk = current; +#endif } 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..00c11579406c 100644 --- a/arch/arm/kernel/return_address.c +++ b/arch/arm/kernel/return_address.c @@ -42,6 +42,10 @@ 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; +#ifdef CONFIG_KRETPROBES + frame.kr_cur = NULL; + frame.tsk = current; +#endif walk_stackframe(&frame, save_return_addr, &data); diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index db798eac7431..75e905508f27 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,11 @@ int notrace unwind_frame(struct stackframe *frame) frame->sp = *(unsigned long *)(fp - 8); frame->pc = *(unsigned long *)(fp - 4); #endif +#ifdef CONFIG_KRETPROBES + if (is_kretprobe_trampoline(frame->pc)) + frame->pc = kretprobe_find_ret_addr(frame->tsk, + (void *)frame->fp, &frame->kr_cur); +#endif return 0; } @@ -156,6 +162,10 @@ 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; } +#ifdef CONFIG_KRETPROBES + frame.kr_cur = NULL; + frame.tsk = tsk; +#endif walk_stackframe(&frame, save_trace, &data); } @@ -173,6 +183,10 @@ 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; +#ifdef CONFIG_KRETPROBES + frame.kr_cur = NULL; + frame.tsk = current; +#endif walk_stackframe(&frame, save_trace, &data); }