[PATCH 6.1.y] riscv: stacktrace: Disable KASAN checks for non-current tasks
From: Jianqiang kang
Date: Mon Mar 23 2026 - 02:31:45 EST
From: Chunyan Zhang <zhangchunyan@xxxxxxxxxxx>
[ Upstream commit 060ea84a484e852b52b938f234bf9b5503a6c910 ]
Unwinding the stack of a task other than current, KASAN would report
"BUG: KASAN: out-of-bounds in walk_stackframe+0x41c/0x460"
There is a same issue on x86 and has been resolved by the commit
84936118bdf3 ("x86/unwind: Disable KASAN checks for non-current tasks")
The solution could be applied to RISC-V too.
This patch also can solve the issue:
https://seclists.org/oss-sec/2025/q4/23
Fixes: 5d8544e2d007 ("RISC-V: Generic library routines and assembly")
Co-developed-by: Jiakai Xu <xujiakai2025@xxxxxxxxxxx>
Signed-off-by: Jiakai Xu <xujiakai2025@xxxxxxxxxxx>
Signed-off-by: Chunyan Zhang <zhangchunyan@xxxxxxxxxxx>
Link: https://lore.kernel.org/r/20251022072608.743484-1-zhangchunyan@xxxxxxxxxxx
[pjw@xxxxxxxxxx: clean up checkpatch issues]
Signed-off-by: Paul Walmsley <pjw@xxxxxxxxxx>
[ Minor conflict resolved. ]
Signed-off-by: Jianqiang kang <jianqkang@xxxxxxx>
---
arch/riscv/kernel/stacktrace.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
index 10e311b2759d..4f78b7962651 100644
--- a/arch/riscv/kernel/stacktrace.c
+++ b/arch/riscv/kernel/stacktrace.c
@@ -16,6 +16,22 @@
#ifdef CONFIG_FRAME_POINTER
+/*
+ * This disables KASAN checking when reading a value from another task's stack,
+ * since the other task could be running on another CPU and could have poisoned
+ * the stack in the meantime.
+ */
+#define READ_ONCE_TASK_STACK(task, x) \
+({ \
+ unsigned long val; \
+ unsigned long addr = x; \
+ if ((task) == current) \
+ val = READ_ONCE(addr); \
+ else \
+ val = READ_ONCE_NOCHECK(addr); \
+ val; \
+})
+
extern asmlinkage void ret_from_exception(void);
static inline int fp_is_valid(unsigned long fp, unsigned long sp)
@@ -68,8 +84,9 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
fp = frame->ra;
pc = regs->ra;
} else {
- fp = frame->fp;
- pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra,
+ fp = READ_ONCE_TASK_STACK(task, frame->fp);
+ pc = READ_ONCE_TASK_STACK(task, frame->ra);
+ pc = ftrace_graph_ret_addr(current, &graph_idx, pc,
&frame->ra);
if (pc == (unsigned long)ret_from_exception) {
if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
--
2.34.1