Skip to content

Commit 060ea84

Browse files
Chunyan ZhangPaul Walmsley
authored andcommitted
riscv: stacktrace: Disable KASAN checks for non-current tasks
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 8493611 ("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: 5d8544e ("RISC-V: Generic library routines and assembly") Co-developed-by: Jiakai Xu <xujiakai2025@iscas.ac.cn> Signed-off-by: Jiakai Xu <xujiakai2025@iscas.ac.cn> Signed-off-by: Chunyan Zhang <zhangchunyan@iscas.ac.cn> Link: https://lore.kernel.org/r/20251022072608.743484-1-zhangchunyan@iscas.ac.cn [pjw@kernel.org: clean up checkpatch issues] Signed-off-by: Paul Walmsley <pjw@kernel.org>
1 parent dcb6fa3 commit 060ea84

1 file changed

Lines changed: 19 additions & 2 deletions

File tree

arch/riscv/kernel/stacktrace.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@
1616

1717
#ifdef CONFIG_FRAME_POINTER
1818

19+
/*
20+
* This disables KASAN checking when reading a value from another task's stack,
21+
* since the other task could be running on another CPU and could have poisoned
22+
* the stack in the meantime.
23+
*/
24+
#define READ_ONCE_TASK_STACK(task, x) \
25+
({ \
26+
unsigned long val; \
27+
unsigned long addr = x; \
28+
if ((task) == current) \
29+
val = READ_ONCE(addr); \
30+
else \
31+
val = READ_ONCE_NOCHECK(addr); \
32+
val; \
33+
})
34+
1935
extern asmlinkage void handle_exception(void);
2036
extern unsigned long ret_from_exception_end;
2137

@@ -69,8 +85,9 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
6985
fp = frame->ra;
7086
pc = regs->ra;
7187
} else {
72-
fp = frame->fp;
73-
pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra,
88+
fp = READ_ONCE_TASK_STACK(task, frame->fp);
89+
pc = READ_ONCE_TASK_STACK(task, frame->ra);
90+
pc = ftrace_graph_ret_addr(current, &graph_idx, pc,
7491
&frame->ra);
7592
if (pc >= (unsigned long)handle_exception &&
7693
pc < (unsigned long)&ret_from_exception_end) {

0 commit comments

Comments
 (0)