From: madvenka@linux.microsoft.com
To: mark.rutland@arm.com, broonie@kernel.org, jpoimboe@redhat.com,
ardb@kernel.org, nobuta.keiya@fujitsu.com,
sjitindarsingh@gmail.com, catalin.marinas@arm.com,
will@kernel.org, jmorris@namei.org,
linux-arm-kernel@lists.infradead.org,
live-patching@vger.kernel.org, linux-kernel@vger.kernel.org,
madvenka@linux.microsoft.com
Subject: [RFC PATCH v1 6/9] arm64: unwinder: Add a reliability check in the unwinder based on DWARF CFI
Date: Thu, 7 Apr 2022 15:25:15 -0500 [thread overview]
Message-ID: <20220407202518.19780-7-madvenka@linux.microsoft.com> (raw)
In-Reply-To: <20220407202518.19780-1-madvenka@linux.microsoft.com>
From: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com>
Introduce a reliability flag in struct stackframe. This will be set to false
if the PC does not have valid DWARF rules or if the frame pointer computed
from the DWARF rules does not match the actual frame pointer.
Now that the unwinder can validate the frame pointer, introduce
arch_stack_walk_reliable().
Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com>
---
arch/arm64/include/asm/stacktrace.h | 6 +++
arch/arm64/kernel/stacktrace.c | 69 +++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 6564a01cc085..93adee4219ed 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -5,6 +5,7 @@
#ifndef __ASM_STACKTRACE_H
#define __ASM_STACKTRACE_H
+#include <linux/dwarf.h>
#include <linux/percpu.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
@@ -35,6 +36,7 @@ struct stack_info {
* A snapshot of a frame record or fp/lr register values, along with some
* accounting information necessary for robust unwinding.
*
+ * @sp: The sp value (CFA) at the call site of the current function.
* @fp: The fp value in the frame record (or the real fp)
* @pc: The lr value in the frame record (or the real lr)
*
@@ -47,8 +49,11 @@ struct stack_info {
* @prev_type: The type of stack this frame record was on, or a synthetic
* value of STACK_TYPE_UNKNOWN. This is used to detect a
* transition from one stack to another.
+ *
+ * @reliable Stack trace is reliable.
*/
struct stackframe {
+ unsigned long sp;
unsigned long fp;
unsigned long pc;
DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES);
@@ -57,6 +62,7 @@ struct stackframe {
#ifdef CONFIG_KRETPROBES
struct llist_node *kr_cur;
#endif
+ bool reliable;
};
extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame);
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 94f83cd44e50..f9ef7a3e7296 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -5,6 +5,7 @@
* Copyright (C) 2012 ARM Ltd.
*/
#include <linux/kernel.h>
+#include <linux/dwarf.h>
#include <linux/export.h>
#include <linux/ftrace.h>
#include <linux/kprobes.h>
@@ -36,8 +37,22 @@
void start_backtrace(struct stackframe *frame, unsigned long fp,
unsigned long pc)
{
+ struct dwarf_rule *rule;
+
+ frame->reliable = true;
frame->fp = fp;
frame->pc = pc;
+ frame->sp = 0;
+ /*
+ * Lookup the dwarf rule for PC. If it exists, initialize the SP
+ * based on the frame pointer passed in.
+ */
+ rule = dwarf_lookup(pc);
+ if (rule)
+ frame->sp = fp - rule->fp_offset;
+ else
+ frame->reliable = false;
+
#ifdef CONFIG_KRETPROBES
frame->kr_cur = NULL;
#endif
@@ -67,6 +82,8 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
{
unsigned long fp = frame->fp;
struct stack_info info;
+ struct dwarf_rule *rule;
+ unsigned long lookup_pc;
if (!tsk)
tsk = current;
@@ -137,6 +154,32 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
frame->pc = kretprobe_find_ret_addr(tsk, (void *)frame->fp, &frame->kr_cur);
#endif
+ /*
+ * If it is the last frame, no need to check dwarf.
+ */
+ if (frame->fp == (unsigned long)task_pt_regs(tsk)->stackframe)
+ return 0;
+
+ if (!frame->reliable) {
+ /*
+ * The sp value cannot be reliably computed anymore because a
+ * previous frame was unreliable.
+ */
+ return 0;
+ }
+ lookup_pc = frame->pc;
+
+ rule = dwarf_lookup(lookup_pc);
+ if (!rule) {
+ frame->reliable = false;
+ return 0;
+ }
+
+ frame->sp += rule->sp_offset;
+ if (frame->fp != (frame->sp + rule->fp_offset)) {
+ frame->reliable = false;
+ return 0;
+ }
return 0;
}
NOKPROBE_SYMBOL(unwind_frame);
@@ -242,4 +285,30 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
walk_stackframe(task, &frame, consume_entry, cookie);
}
+noinline int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,
+ void *cookie, struct task_struct *task)
+{
+ struct stackframe frame;
+ int ret = 0;
+
+ if (task == current) {
+ start_backtrace(&frame,
+ (unsigned long)__builtin_frame_address(1),
+ (unsigned long)__builtin_return_address(0));
+ } else {
+ start_backtrace(&frame, thread_saved_fp(task),
+ thread_saved_pc(task));
+ }
+
+ while (!ret) {
+ if (!frame.reliable)
+ return -EINVAL;
+ if (!consume_entry(cookie, frame.pc))
+ return -EINVAL;
+ ret = unwind_frame(task, &frame);
+ }
+
+ return ret == -ENOENT ? 0 : -EINVAL;
+}
+
#endif
--
2.25.1
next prev parent reply other threads:[~2022-04-07 20:38 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <95691cae4f4504f33d0fc9075541b1e7deefe96f>
2022-01-17 14:55 ` [PATCH v13 00/11] arm64: Reorganize the unwinder and implement stack trace reliability checks madvenka
2022-01-17 14:55 ` [PATCH v13 01/11] arm64: Remove NULL task check from unwind_frame() madvenka
2022-01-17 14:55 ` [PATCH v13 02/11] arm64: Rename unwinder functions madvenka
2022-01-17 14:56 ` [PATCH v13 03/11] arm64: Rename stackframe to unwind_state madvenka
2022-01-17 14:56 ` [PATCH v13 04/11] arm64: Split unwind_init() madvenka
2022-02-02 18:44 ` Mark Brown
2022-02-03 0:26 ` Madhavan T. Venkataraman
2022-02-03 0:39 ` Madhavan T. Venkataraman
2022-02-03 11:29 ` Mark Brown
2022-02-15 13:07 ` Mark Rutland
2022-02-15 18:04 ` Madhavan T. Venkataraman
2022-01-17 14:56 ` [PATCH v13 05/11] arm64: Copy the task argument to unwind_state madvenka
2022-02-02 18:45 ` Mark Brown
2022-02-15 13:22 ` Mark Rutland
2022-02-22 16:53 ` Madhavan T. Venkataraman
2022-01-17 14:56 ` [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind() madvenka
2022-02-02 18:46 ` Mark Brown
2022-02-03 0:34 ` Madhavan T. Venkataraman
2022-02-03 11:30 ` Mark Brown
2022-02-03 14:45 ` Madhavan T. Venkataraman
2022-02-15 13:39 ` Mark Rutland
2022-02-15 18:12 ` Madhavan T. Venkataraman
2022-03-07 16:51 ` Madhavan T. Venkataraman
2022-03-07 17:01 ` Mark Brown
2022-03-08 22:00 ` Madhavan T. Venkataraman
2022-03-09 11:47 ` Mark Brown
2022-03-09 15:34 ` Madhavan T. Venkataraman
2022-03-10 8:33 ` Miroslav Benes
2022-03-10 12:36 ` Madhavan T. Venkataraman
2022-03-16 3:43 ` Josh Poimboeuf
2022-04-08 14:44 ` Mark Rutland
2022-04-08 17:58 ` Mark Rutland
2022-04-10 17:42 ` Madhavan T. Venkataraman
2022-04-10 17:33 ` Madhavan T. Venkataraman
2022-04-10 17:45 ` Madhavan T. Venkataraman
2022-01-17 14:56 ` [PATCH v13 07/11] arm64: Make the unwind loop in unwind() similar to other architectures madvenka
2022-01-17 14:56 ` [PATCH v13 08/11] arm64: Introduce stack trace reliability checks in the unwinder madvenka
2022-01-17 14:56 ` [PATCH v13 09/11] arm64: Create a list of SYM_CODE functions, check return PC against list madvenka
2022-01-17 14:56 ` [PATCH v13 10/11] arm64: Introduce arch_stack_walk_reliable() madvenka
2022-01-17 14:56 ` [PATCH v13 11/11] arm64: Select HAVE_RELIABLE_STACKTRACE madvenka
2022-01-25 5:21 ` nobuta.keiya
2022-01-25 13:43 ` Madhavan T. Venkataraman
2022-01-26 10:20 ` nobuta.keiya
2022-01-26 17:14 ` Madhavan T. Venkataraman
2022-01-27 1:13 ` nobuta.keiya
2022-01-26 17:16 ` Mark Brown
2022-04-07 20:25 ` [RFC PATCH v1 0/9] arm64: livepatch: Use DWARF Call Frame Information for frame pointer validation madvenka
2022-04-07 20:25 ` [RFC PATCH v1 1/9] objtool: Parse DWARF Call Frame Information in object files madvenka
2022-04-07 20:25 ` [RFC PATCH v1 2/9] objtool: Generate DWARF rules and place them in a special section madvenka
2022-04-07 20:25 ` [RFC PATCH v1 3/9] dwarf: Build the kernel with DWARF information madvenka
2022-04-07 20:25 ` [RFC PATCH v1 4/9] dwarf: Implement DWARF rule processing in the kernel madvenka
2022-04-07 20:25 ` [RFC PATCH v1 5/9] dwarf: Implement DWARF support for modules madvenka
2022-04-07 20:25 ` madvenka [this message]
2022-04-07 20:25 ` [RFC PATCH v1 7/9] arm64: dwarf: Implement unwind hints madvenka
2022-04-07 20:25 ` [RFC PATCH v1 8/9] dwarf: Miscellaneous changes required for enabling livepatch madvenka
2022-04-07 20:25 ` [RFC PATCH v1 9/9] dwarf: Enable livepatch for ARM64 madvenka
2022-04-08 0:21 ` [RFC PATCH v1 0/9] arm64: livepatch: Use DWARF Call Frame Information for frame pointer validation Josh Poimboeuf
2022-04-08 11:41 ` Peter Zijlstra
2022-04-11 17:26 ` Madhavan T. Venkataraman
2022-04-11 17:18 ` Madhavan T. Venkataraman
2022-04-12 8:32 ` Chen Zhongjin
2022-04-16 0:56 ` Josh Poimboeuf
2022-04-18 12:28 ` Chen Zhongjin
2022-04-18 16:11 ` Josh Poimboeuf
2022-04-18 18:38 ` Madhavan T. Venkataraman
[not found] ` <844b3ede-eddb-cbe6-80e0-3529e2da2eb6@huawei.com>
2022-04-12 17:27 ` Madhavan T. Venkataraman
2022-04-16 1:07 ` Josh Poimboeuf
2022-04-14 14:11 ` Madhavan T. Venkataraman
2022-04-08 10:55 ` Peter Zijlstra
2022-04-08 11:54 ` Peter Zijlstra
2022-04-08 14:34 ` Josh Poimboeuf
2022-04-10 17:47 ` Madhavan T. Venkataraman
2022-04-11 16:34 ` Josh Poimboeuf
2022-04-08 12:06 ` Peter Zijlstra
2022-04-11 17:35 ` Madhavan T. Venkataraman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220407202518.19780-7-madvenka@linux.microsoft.com \
--to=madvenka@linux.microsoft.com \
--cc=ardb@kernel.org \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=jmorris@namei.org \
--cc=jpoimboe@redhat.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=nobuta.keiya@fujitsu.com \
--cc=sjitindarsingh@gmail.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).