[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20251023090632.269121-1-wutengda@huaweicloud.com>
Date: Thu, 23 Oct 2025 09:06:32 +0000
From: Tengda Wu <wutengda@...weicloud.com>
To: Borislav Petkov <bp@...en8.de>
Cc: x86@...nel.org,
jpoimboe@...nel.org,
Andrey Ryabinin <ryabinin.a.a@...il.com>,
Thomas Gleixner <tglx@...utronix.de>,
Alexander Potapenko <glider@...gle.com>,
Andrey Konovalov <andreyknvl@...il.com>,
Dave Hansen <dave.hansen@...ux.intel.com>,
Dmitry Vyukov <dvyukov@...gle.com>,
Ingo Molnar <mingo@...hat.com>,
linux-kernel@...r.kernel.org,
Tengda Wu <wutengda@...weicloud.com>
Subject: [PATCH -next v4] x86/dumpstack: Prevent KASAN false positive warnings in __show_regs
When triggering a stack dump via sysrq (echo t > /proc/sysrq-trigger),
KASAN may report false-positive out-of-bounds access:
BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340
Call Trace:
dump_stack_lvl
print_address_description.constprop.0
print_report
__show_regs
show_trace_log_lvl
sched_show_task
show_state_filter
sysrq_handle_showstate
__handle_sysrq
write_sysrq_trigger
proc_reg_write
vfs_write
ksys_write
do_syscall_64
entry_SYSCALL_64_after_hwframe
The issue occurs as follows:
Task A (walk other tasks' stacks) Task B (running)
1. echo t > /proc/sysrq-trigger
show_trace_log_lvl
regs = unwind_get_entry_regs()
show_regs_if_on_stack(regs)
2. The stack value pointed by
`regs` keeps changing, and
so are the tags in its
KASAN shadow region.
__show_regs(regs)
regs->ax, regs->bx, ...
3. hit KASAN redzones, OOB
When task A walks task B's stack without suspending it, the continuous
changes in task B's stack (and corresponding KASAN shadow tags) may cause
task A to hit KASAN redzones when accessing obsolete values on the stack,
resulting in false positive reports.
Simply stopping the task before unwinding is not a viable fix, as it
would alter the state we intend to inspect. This is especially true for
diagnosing misbehaving tasks (e.g., in a hard lockup), where stopping
might fail or hide the root cause by changing the call stack.
Therefore, fix this by disabling KASAN checks during asynchronous stack
unwinding, which is identified when the unwinding task does not match the
current task (task != current).
Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack")
Signed-off-by: Tengda Wu <wutengda@...weicloud.com>
Acked-by: Josh Poimboeuf <jpoimboe@...nel.org>
Reviewed-by: Andrey Ryabinin <ryabinin.a.a@...il.com>
---
v4: Address Boris comments, introduce __show_trace_log_lvl and wrap it
with kasan disable/enable, rewrite the commit message.
v3: https://lore.kernel.org/all/20250830092556.3360776-1-wutengda@huaweicloud.com/
v2: https://lore.kernel.org/all/20250829094744.3133324-1-wutengda@huaweicloud.com/
v1: https://lore.kernel.org/all/20250818130715.2904264-1-wutengda@huaweicloud.com/
---
arch/x86/kernel/dumpstack.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 71ee20102a8a..516740fba207 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -181,7 +181,7 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs,
* in false positive reports. Disable instrumentation to avoid those.
*/
__no_kmsan_checks
-static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
+static void __show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
unsigned long *stack, const char *log_lvl)
{
struct unwind_state state;
@@ -303,6 +303,25 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
}
}
+static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
+ unsigned long *stack, const char *log_lvl)
+{
+ /*
+ * Disable KASAN to avoid false positives during walking another
+ * task's stacks, as values on these stacks may change concurrently
+ * with task execution.
+ */
+ bool disable_kasan = task && task != current;
+
+ if (disable_kasan)
+ kasan_disable_current();
+
+ __show_trace_log_lvl(task, regs, stack, log_lvl);
+
+ if (disable_kasan)
+ kasan_enable_current();
+}
+
void show_stack(struct task_struct *task, unsigned long *sp,
const char *loglvl)
{
--
2.34.1
Powered by blists - more mailing lists