[PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()

Tengda Wu posted 1 patch 1 month, 2 weeks ago
arch/x86/include/asm/kdebug.h | 2 +-
arch/x86/kernel/process_32.c  | 1 +
arch/x86/kernel/process_64.c  | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
[PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Tengda Wu 1 month, 2 weeks ago
When process A accesses process B's `regs` from stack memory through
__show_regs(), the stack of process B keeps changing during runtime.
This causes false positives like "stack out-of-bounds" [1] or
"out-of-bounds" [2] warnings when reading `regs` contents.

Add __no_sanitize_address attribute to __show_regs() to suppress these
false positives while maintaining the ability to debug register states
across processes.

[1] https://lore.kernel.org/all/000000000000cb8e3a05c4ed84bb@google.com/
[2] A similar KASAN report:
[332706.552324] BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340
[332706.552433] Read of size 8 at addr ffff88d24999fb20 by task sysrq_t_test.sh/3977032
[332706.552562]
[332706.552652] CPU: 36 PID: 3977032 Comm: sysrq_t_test.sh Kdump: loaded Not tainted 6.6.0+ #20
[332706.552783] Hardware name: Huawei RH2288H V3/BC11HGSA0, BIOS 3.35 10/20/2016
[332706.552906] Call Trace:
[332706.552998]  <TASK>
[332706.553089]  dump_stack_lvl+0x32/0x50
[332706.553193]  print_address_description.constprop.0+0x6b/0x3d0
[332706.553303]  print_report+0xbe/0x280
[332706.553409]  ? __virt_addr_valid+0xed/0x160
[332706.553512]  ? __show_regs+0x4b/0x340
[332706.553612]  kasan_report+0xa8/0xe0
[332706.553716]  ? __show_regs+0x4b/0x340
[332706.553816]  ? asm_exc_page_fault+0x22/0x30
[332706.553919]  __show_regs+0x4b/0x340
[332706.554021]  ? asm_exc_page_fault+0x22/0x30
[332706.554123]  show_trace_log_lvl+0x274/0x3b0
[332706.554229]  ? load_elf_binary+0xf6e/0x1610
[332706.554330]  ? rep_stos_alternative+0x40/0x80
[332706.554439]  sched_show_task+0x211/0x290
[332706.554544]  ? __pfx_sched_show_task+0x10/0x10
[332706.554648]  ? _find_next_bit+0x6/0xc0
[332706.554749]  ? _find_next_bit+0x37/0xc0
[332706.554852]  show_state_filter+0x72/0x130
[332706.554956]  sysrq_handle_showstate+0x7/0x10
[332706.555062]  __handle_sysrq+0x146/0x2d0
[332706.555165]  write_sysrq_trigger+0x2f/0x50
[332706.555270]  proc_reg_write+0xdd/0x140
[332706.555372]  vfs_write+0x1ff/0x5f0
[332706.555474]  ? __pfx_vfs_write+0x10/0x10
[332706.555576]  ? __pfx___handle_mm_fault+0x10/0x10
[332706.555682]  ? __fget_light+0x99/0xf0
[332706.555785]  ksys_write+0xb8/0x150
[332706.555887]  ? __pfx_ksys_write+0x10/0x10
[332706.555989]  ? ktime_get_coarse_real_ts64+0x4e/0x70
[332706.556094]  do_syscall_64+0x55/0x100
[332706.556196]  entry_SYSCALL_64_after_hwframe+0x78/0xe2

Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack")
Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
---
 arch/x86/include/asm/kdebug.h | 2 +-
 arch/x86/kernel/process_32.c  | 1 +
 arch/x86/kernel/process_64.c  | 1 +
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h
index d1514e70477b..2e0570d75bbc 100644
--- a/arch/x86/include/asm/kdebug.h
+++ b/arch/x86/include/asm/kdebug.h
@@ -36,7 +36,7 @@ extern void die(const char *, struct pt_regs *,long);
 void die_addr(const char *str, struct pt_regs *regs, long err, long gp_addr);
 extern int __must_check __die(const char *, struct pt_regs *, long);
 extern void show_stack_regs(struct pt_regs *regs);
-extern void __show_regs(struct pt_regs *regs, enum show_regs_mode,
+extern void __no_sanitize_address __show_regs(struct pt_regs *regs, enum show_regs_mode,
 			const char *log_lvl);
 extern void show_iret_regs(struct pt_regs *regs, const char *log_lvl);
 extern unsigned long oops_begin(void);
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 3ef15c2f152f..1b7ed4dee18b 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -56,6 +56,7 @@
 
 #include "process.h"
 
+__no_sanitize_address
 void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
 		 const char *log_lvl)
 {
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 52a5c03c353c..921c96154ce3 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -66,6 +66,7 @@
 #include "process.h"
 
 /* Prints also some state that isn't saved in the pt_regs */
+__no_sanitize_address
 void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
 		 const char *log_lvl)
 {
-- 
2.34.1
Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Andrey Ryabinin 1 month, 1 week ago

On 8/18/25 3:07 PM, Tengda Wu wrote:
> When process A accesses process B's `regs` from stack memory through
> __show_regs(), the stack of process B keeps changing during runtime.
> This causes false positives like "stack out-of-bounds" [1] or
> "out-of-bounds" [2] warnings when reading `regs` contents.
> 
> Add __no_sanitize_address attribute to __show_regs() to suppress these
> false positives while maintaining the ability to debug register states
> across processes.
> 
> [1] https://lore.kernel.org/all/000000000000cb8e3a05c4ed84bb@google.com/
> [2] A similar KASAN report:
> [332706.552324] BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340
> [332706.552433] Read of size 8 at addr ffff88d24999fb20 by task sysrq_t_test.sh/3977032
> [332706.552562]
> [332706.552652] CPU: 36 PID: 3977032 Comm: sysrq_t_test.sh Kdump: loaded Not tainted 6.6.0+ #20
> [332706.552783] Hardware name: Huawei RH2288H V3/BC11HGSA0, BIOS 3.35 10/20/2016
> [332706.552906] Call Trace:
> [332706.552998]  <TASK>
> [332706.553089]  dump_stack_lvl+0x32/0x50
> [332706.553193]  print_address_description.constprop.0+0x6b/0x3d0
> [332706.553303]  print_report+0xbe/0x280
> [332706.553409]  ? __virt_addr_valid+0xed/0x160
> [332706.553512]  ? __show_regs+0x4b/0x340
> [332706.553612]  kasan_report+0xa8/0xe0
> [332706.553716]  ? __show_regs+0x4b/0x340
> [332706.553816]  ? asm_exc_page_fault+0x22/0x30
> [332706.553919]  __show_regs+0x4b/0x340
> [332706.554021]  ? asm_exc_page_fault+0x22/0x30
> [332706.554123]  show_trace_log_lvl+0x274/0x3b0
> [332706.554229]  ? load_elf_binary+0xf6e/0x1610
> [332706.554330]  ? rep_stos_alternative+0x40/0x80
> [332706.554439]  sched_show_task+0x211/0x290
> [332706.554544]  ? __pfx_sched_show_task+0x10/0x10
> [332706.554648]  ? _find_next_bit+0x6/0xc0
> [332706.554749]  ? _find_next_bit+0x37/0xc0
> [332706.554852]  show_state_filter+0x72/0x130
> [332706.554956]  sysrq_handle_showstate+0x7/0x10
> [332706.555062]  __handle_sysrq+0x146/0x2d0
> [332706.555165]  write_sysrq_trigger+0x2f/0x50
> [332706.555270]  proc_reg_write+0xdd/0x140
> [332706.555372]  vfs_write+0x1ff/0x5f0
> [332706.555474]  ? __pfx_vfs_write+0x10/0x10
> [332706.555576]  ? __pfx___handle_mm_fault+0x10/0x10
> [332706.555682]  ? __fget_light+0x99/0xf0
> [332706.555785]  ksys_write+0xb8/0x150
> [332706.555887]  ? __pfx_ksys_write+0x10/0x10
> [332706.555989]  ? ktime_get_coarse_real_ts64+0x4e/0x70
> [332706.556094]  do_syscall_64+0x55/0x100
> [332706.556196]  entry_SYSCALL_64_after_hwframe+0x78/0xe2
> 
> Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack")
> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
> ---
>  arch/x86/include/asm/kdebug.h | 2 +-
>  arch/x86/kernel/process_32.c  | 1 +
>  arch/x86/kernel/process_64.c  | 1 +
>  3 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h
> index d1514e70477b..2e0570d75bbc 100644
> --- a/arch/x86/include/asm/kdebug.h
> +++ b/arch/x86/include/asm/kdebug.h
> @@ -36,7 +36,7 @@ extern void die(const char *, struct pt_regs *,long);
>  void die_addr(const char *str, struct pt_regs *regs, long err, long gp_addr);
>  extern int __must_check __die(const char *, struct pt_regs *, long);
>  extern void show_stack_regs(struct pt_regs *regs);
> -extern void __show_regs(struct pt_regs *regs, enum show_regs_mode,
> +extern void __no_sanitize_address __show_regs(struct pt_regs *regs, enum show_regs_mode,
>  			const char *log_lvl);
>  extern void show_iret_regs(struct pt_regs *regs, const char *log_lvl);
>  extern unsigned long oops_begin(void);
> diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
> index 3ef15c2f152f..1b7ed4dee18b 100644
> --- a/arch/x86/kernel/process_32.c
> +++ b/arch/x86/kernel/process_32.c
> @@ -56,6 +56,7 @@
>  
>  #include "process.h"
>  
> +__no_sanitize_address
>  void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
>  		 const char *log_lvl)
>  {
> diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
> index 52a5c03c353c..921c96154ce3 100644
> --- a/arch/x86/kernel/process_64.c
> +++ b/arch/x86/kernel/process_64.c
> @@ -66,6 +66,7 @@
>  #include "process.h"
>  
>  /* Prints also some state that isn't saved in the pt_regs */
> +__no_sanitize_address
>  void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
>  		 const char *log_lvl)
>  {


__no_sanitize_address affects only __show_regs() function.
But the `regs` are passed down in show_iret_regs()->show_ip()->show_opcodes()
and all these also accesses `regs`

I see several options here:

1. Use kasan_disable_current()/kasan_enable_current() to wrap code accessing `regs`.
And maybe something like:
         if (!on_current_stack(regs))
                 kasan_disable_current();

so we skip kasan reports only if `regs` belong to other task.

2. Sprinkle over __no_sanitize_address all functions accessing `regs`.
But this disable all memory access checks all the time in these functions.

3. Use READ_ONCE_NOCHECK() to read regs->

4. Introduce memcpy_no_sanitize_address(), and use it to copy snapshot of `regs`
somewhere (on the stack of current task ?). But pt_regs is 168 bytes, I'm not sure if this
is acceptable stack usage increment.
Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Tengda Wu 1 month ago
Hi Andrey,

On 2025/8/27 22:45, Andrey Ryabinin wrote:
> 
> 
> On 8/18/25 3:07 PM, Tengda Wu wrote:
>> When process A accesses process B's `regs` from stack memory through
>> __show_regs(), the stack of process B keeps changing during runtime.
>> This causes false positives like "stack out-of-bounds" [1] or
>> "out-of-bounds" [2] warnings when reading `regs` contents.
>>
>> Add __no_sanitize_address attribute to __show_regs() to suppress these
>> false positives while maintaining the ability to debug register states
>> across processes.
>>
>> [1] https://lore.kernel.org/all/000000000000cb8e3a05c4ed84bb@google.com/
>> [2] A similar KASAN report:
>> [332706.552324] BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340
>> [332706.552433] Read of size 8 at addr ffff88d24999fb20 by task sysrq_t_test.sh/3977032
>> [332706.552562]
>> [332706.552652] CPU: 36 PID: 3977032 Comm: sysrq_t_test.sh Kdump: loaded Not tainted 6.6.0+ #20
>> [332706.552783] Hardware name: Huawei RH2288H V3/BC11HGSA0, BIOS 3.35 10/20/2016
>> [332706.552906] Call Trace:
>> [332706.552998]  <TASK>
>> [332706.553089]  dump_stack_lvl+0x32/0x50
>> [332706.553193]  print_address_description.constprop.0+0x6b/0x3d0
>> [332706.553303]  print_report+0xbe/0x280
>> [332706.553409]  ? __virt_addr_valid+0xed/0x160
>> [332706.553512]  ? __show_regs+0x4b/0x340
>> [332706.553612]  kasan_report+0xa8/0xe0
>> [332706.553716]  ? __show_regs+0x4b/0x340
>> [332706.553816]  ? asm_exc_page_fault+0x22/0x30
>> [332706.553919]  __show_regs+0x4b/0x340
>> [332706.554021]  ? asm_exc_page_fault+0x22/0x30
>> [332706.554123]  show_trace_log_lvl+0x274/0x3b0
>> [332706.554229]  ? load_elf_binary+0xf6e/0x1610
>> [332706.554330]  ? rep_stos_alternative+0x40/0x80
>> [332706.554439]  sched_show_task+0x211/0x290
>> [332706.554544]  ? __pfx_sched_show_task+0x10/0x10
>> [332706.554648]  ? _find_next_bit+0x6/0xc0
>> [332706.554749]  ? _find_next_bit+0x37/0xc0
>> [332706.554852]  show_state_filter+0x72/0x130
>> [332706.554956]  sysrq_handle_showstate+0x7/0x10
>> [332706.555062]  __handle_sysrq+0x146/0x2d0
>> [332706.555165]  write_sysrq_trigger+0x2f/0x50
>> [332706.555270]  proc_reg_write+0xdd/0x140
>> [332706.555372]  vfs_write+0x1ff/0x5f0
>> [332706.555474]  ? __pfx_vfs_write+0x10/0x10
>> [332706.555576]  ? __pfx___handle_mm_fault+0x10/0x10
>> [332706.555682]  ? __fget_light+0x99/0xf0
>> [332706.555785]  ksys_write+0xb8/0x150
>> [332706.555887]  ? __pfx_ksys_write+0x10/0x10
>> [332706.555989]  ? ktime_get_coarse_real_ts64+0x4e/0x70
>> [332706.556094]  do_syscall_64+0x55/0x100
>> [332706.556196]  entry_SYSCALL_64_after_hwframe+0x78/0xe2
>>
>> Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack")
>> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
>> ---
>>  arch/x86/include/asm/kdebug.h | 2 +-
>>  arch/x86/kernel/process_32.c  | 1 +
>>  arch/x86/kernel/process_64.c  | 1 +
>>  3 files changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h
>> index d1514e70477b..2e0570d75bbc 100644
>> --- a/arch/x86/include/asm/kdebug.h
>> +++ b/arch/x86/include/asm/kdebug.h
>> @@ -36,7 +36,7 @@ extern void die(const char *, struct pt_regs *,long);
>>  void die_addr(const char *str, struct pt_regs *regs, long err, long gp_addr);
>>  extern int __must_check __die(const char *, struct pt_regs *, long);
>>  extern void show_stack_regs(struct pt_regs *regs);
>> -extern void __show_regs(struct pt_regs *regs, enum show_regs_mode,
>> +extern void __no_sanitize_address __show_regs(struct pt_regs *regs, enum show_regs_mode,
>>  			const char *log_lvl);
>>  extern void show_iret_regs(struct pt_regs *regs, const char *log_lvl);
>>  extern unsigned long oops_begin(void);
>> diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
>> index 3ef15c2f152f..1b7ed4dee18b 100644
>> --- a/arch/x86/kernel/process_32.c
>> +++ b/arch/x86/kernel/process_32.c
>> @@ -56,6 +56,7 @@
>>  
>>  #include "process.h"
>>  
>> +__no_sanitize_address
>>  void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
>>  		 const char *log_lvl)
>>  {
>> diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
>> index 52a5c03c353c..921c96154ce3 100644
>> --- a/arch/x86/kernel/process_64.c
>> +++ b/arch/x86/kernel/process_64.c
>> @@ -66,6 +66,7 @@
>>  #include "process.h"
>>  
>>  /* Prints also some state that isn't saved in the pt_regs */
>> +__no_sanitize_address
>>  void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
>>  		 const char *log_lvl)
>>  {
> 
> 
> __no_sanitize_address affects only __show_regs() function.
> But the `regs` are passed down in show_iret_regs()->show_ip()->show_opcodes()
> and all these also accesses `regs`

Indeed. Thanks for pointing that out.

> 
> I see several options here:
> 
> 1. Use kasan_disable_current()/kasan_enable_current() to wrap code accessing `regs`.
> And maybe something like:
>          if (!on_current_stack(regs))
>                  kasan_disable_current();
> 
> so we skip kasan reports only if `regs` belong to other task.

This looks like the best fit.

> 
> 2. Sprinkle over __no_sanitize_address all functions accessing `regs`.
> But this disable all memory access checks all the time in these functions.
> 

As Dave said, this does not provide finer-grained control than Option 1.

> 3. Use READ_ONCE_NOCHECK() to read regs->

This might affect code readability, as there are too many `regs->xxx`
inside these functions.

> 
> 4. Introduce memcpy_no_sanitize_address(), and use it to copy snapshot of `regs`
> somewhere (on the stack of current task ?). But pt_regs is 168 bytes, I'm not sure if this
> is acceptable stack usage increment.

This sounds a bit complicated.


So, for Option 1:

It seems there's no existing on_current_stack function available.
Implementing an on_current_stack function would be somewhat
challenging for me. 

How about just check the task directly inside show_trace_log_lvl?
I've traced all kernel paths calling __show_regs() and found that
asynchronous stack walkers always reaches here. — seems suitable?

Here is a sample patch:

diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 71ee20102a8a..e519aeb00705 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -189,9 +189,15 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
        unsigned long visit_mask = 0;
        int graph_idx = 0;
        bool partial = false;
+       bool kasan_disabled = false;
 
        printk("%sCall Trace:\n", log_lvl);
 
+       if (task != current) {
+               kasan_disable_current();
+               kasan_disabled = true;
+       }
+
        unwind_start(&state, task, regs, stack);
        stack = stack ?: get_stack_pointer(task, regs);
        regs = unwind_get_entry_regs(&state, &partial);
@@ -301,6 +307,9 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
                if (stack_name)
                        printk("%s </%s>\n", log_lvl, stack_name);
        }
+
+       if (kasan_disabled)
+               kasan_enable_current();
 }


Best regards,
Tengda

Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Josh Poimboeuf 1 month ago
On Thu, Aug 28, 2025 at 08:06:17PM +0800, Tengda Wu wrote:
> +++ b/arch/x86/kernel/dumpstack.c
> @@ -189,9 +189,15 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
>         unsigned long visit_mask = 0;
>         int graph_idx = 0;
>         bool partial = false;
> +       bool kasan_disabled = false;
>  
>         printk("%sCall Trace:\n", log_lvl);
>  
> +       if (task != current) {
> +               kasan_disable_current();
> +               kasan_disabled = true;
> +       }

Looks reasonable to me, though note that some callers pass a NULL @task
to indicate 'current'.

(No idea why, that subtlety should probably be removed...)

So this might need to be

	if (task && task != current) {
		...

-- 
Josh
Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Tengda Wu 1 month ago

On 2025/8/29 3:16, Josh Poimboeuf wrote:
> On Thu, Aug 28, 2025 at 08:06:17PM +0800, Tengda Wu wrote:
>> +++ b/arch/x86/kernel/dumpstack.c
>> @@ -189,9 +189,15 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
>>         unsigned long visit_mask = 0;
>>         int graph_idx = 0;
>>         bool partial = false;
>> +       bool kasan_disabled = false;
>>  
>>         printk("%sCall Trace:\n", log_lvl);
>>  
>> +       if (task != current) {
>> +               kasan_disable_current();
>> +               kasan_disabled = true;
>> +       }
> 
> Looks reasonable to me, though note that some callers pass a NULL @task
> to indicate 'current'.
> 
> (No idea why, that subtlety should probably be removed...)
> 
> So this might need to be
> 
> 	if (task && task != current) {
> 		...
> 

Dave mentioned that there's an object_is_on_stack available, which is
essentially on_current_stack. I will try using it and send out v2.

Thanks,
Tengda
Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Dave Hansen 1 month ago
On 8/28/25 05:06, Tengda Wu wrote:
> It seems there's no existing on_current_stack function available.
> Implementing an on_current_stack function would be somewhat
> challenging for me. 

Is there some reason that object_is_on_stack() won't work?
Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Tengda Wu 1 month ago

On 2025/8/28 22:13, Dave Hansen wrote:
> On 8/28/25 05:06, Tengda Wu wrote:
>> It seems there's no existing on_current_stack function available.
>> Implementing an on_current_stack function would be somewhat
>> challenging for me. 
> 
> Is there some reason that object_is_on_stack() won't work?

Ah, that's what it's called! Yes, object_is_on_stack() should work
perfectly for that. Thanks for the clarification.

-- Tengda
Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Dave Hansen 1 month, 1 week ago
On 8/18/25 06:07, Tengda Wu wrote:
> +__no_sanitize_address
>  void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
>  		 const char *log_lvl)

I'd feel a lot better about this if it didn't just disable KASAN for the
whole function. Surely there are other __show_regs() users that could
benefit from sanitizer coverage.

Can we limit the impact to just the asynchronous (unsafe) stack walkers?
If it's just for sysrq, this seems like the kind of thing we could just
a flag somewhere and have KASAN suppress the warning. Or to generically
tell KASAN that we might be doing accesses in a certain memory range
that are unsafe.

I'm also adding Peter and Josh to cc. Seems like the kind of thing they
might have an opinion on.
Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Tengda Wu 1 month ago

On 2025/8/27 22:36, Dave Hansen wrote:
> On 8/18/25 06:07, Tengda Wu wrote:
>> +__no_sanitize_address
>>  void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
>>  		 const char *log_lvl)
> 
> I'd feel a lot better about this if it didn't just disable KASAN for the
> whole function. Surely there are other __show_regs() users that could
> benefit from sanitizer coverage.
> 
> Can we limit the impact to just the asynchronous (unsafe) stack walkers?
> If it's just for sysrq, this seems like the kind of thing we could just
> a flag somewhere and have KASAN suppress the warning. Or to generically
> tell KASAN that we might be doing accesses in a certain memory range
> that are unsafe.
> 
> I'm also adding Peter and Josh to cc. Seems like the kind of thing they
> might have an opinion on.

I see what you mean. Andrey has provided several approaches — perhaps we
can make a selection from those.

Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Dave Hansen 1 month, 2 weeks ago
On 8/18/25 06:07, Tengda Wu wrote:
> When process A accesses process B's `regs` from stack memory through
> __show_regs(), the stack of process B keeps changing during runtime.
> This causes false positives like "stack out-of-bounds" [1] or
> "out-of-bounds" [2] warnings when reading `regs` contents.

Could you explain a little bit more how you know that these are false
positives?
Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Tengda Wu 1 month, 2 weeks ago

On 2025/8/21 5:36, Dave Hansen wrote:
> On 8/18/25 06:07, Tengda Wu wrote:
>> When process A accesses process B's `regs` from stack memory through
>> __show_regs(), the stack of process B keeps changing during runtime.
>> This causes false positives like "stack out-of-bounds" [1] or
>> "out-of-bounds" [2] warnings when reading `regs` contents.
> 
> Could you explain a little bit more how you know that these are false
> positives?

Thanks for the question. We believe this is a false positive caused by a
race condition during asynchronous stack tracing of a running process:

Process A (stack trace all processes)         Process 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 data pointed by
                                                 `regs` keeps changing, and
                                                 so are the markings in its
                                                 KASAN shadow region.
    __show_regs(regs)
      regs->ax, regs->bx, ...
        3. hit KASAN redzones, OOB

When process A stacks process B without suspending it, the continuous
changes in process B's stack (and corresponding KASAN shadow markings)
may cause process A to hit KASAN redzones when accessing obsolete `regs`
addresses, resulting in false positive reports.

A sample error log for this scenario is shown below:

[332706.551830] task:cat             state:R  running task     stack:0     pid:3983623 ppid:3977902 flags:0x00004002
[332706.551847] Call Trace:
[332706.551853]  <TASK>
[332706.551860]  __schedule+0x809/0x1050
[332706.551873]  ? __pfx___schedule+0x10/0x10
[332706.551885]  ? __stack_depot_save+0x34/0x340
[332706.551899]  schedule+0x82/0x160
[332706.551911]  io_schedule+0x68/0xa0
[332706.551923]  __folio_lock_killable+0x1db/0x410
[332706.551940]  ? __pfx___folio_lock_killable+0x10/0x10
[332706.551955]  ? __pfx_wake_page_function+0x10/0x10
[332706.551969]  ? __filemap_get_folio+0x4b/0x3d0
[332706.551982]  filemap_fault+0x67a/0xbd0
[332706.551996]  ? __pfx_filemap_fault+0x10/0x10
[332706.552008]  ? policy_node+0x8a/0xa0
[332706.552021]  ? __mod_node_page_state+0x23/0xf0
[332706.552035]  __do_fault+0x6d/0x340
[332706.552048]  do_cow_fault+0xdd/0x300
[332706.552061]  do_fault+0x141/0x1e0
[332706.552074]  __handle_mm_fault+0x839/0xa70
[332706.552089]  ? __pfx___handle_mm_fault+0x10/0x10
[332706.552105]  ? find_vma+0x6a/0x90
[332706.552117]  handle_mm_fault+0x27d/0x470
[332706.552132]  exc_page_fault+0x336/0x6d0
[332706.552145]  asm_exc_page_fault+0x22/0x30
[332706.552157] RIP: 0010:rep_stos_alternative+0x40/0x80                                         --- (1)
[332706.552173] Code: Unable to access opcode bytes at 0x7ffe929c4fd6.                           --- (2)
[332706.552181] RSP: 3fa6:ffff88ba5e554200 EFLAGS: ffffffff9d50c0e0 ORIG_RAX: ffff88ba5e554200   --- (3)
[332706.552195] ==================================================================
[332706.552324] BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340                              --- (4)
[332706.552433] Read of size 8 at addr ffff88d24999fb20 by task sysrq_t_test.sh/3977032

We focus on logs (1) to (4):
 * Log (1) shows the current regs->ip (a kernel-mode address);
 * Log (2) displays regs->ip - PROLOGUE_SIZE, which deviates significantly
   from kernel-mode addresses, indicating regs->ip has changed.
 * Log (3) then reveals anomalous values in regs->{ss,sp,flags}.
 * Finally, Log (4) reports a KASAN OOB error when accessing regs->bx.

Stack tracing a running task cannot guarantee the accuracy of the printed
regs values, but accessing regs addresses does not cause kernel instability.
Similar cases have been consistently handled this way in the past. [1][2]
We therefore consider this a KASAN false positive.

[1] https://lore.kernel.org/all/20220915150417.722975-40-glider@google.com/T/#u
[2] https://lore.kernel.org/all/5f6e80c4b0c7f7f0b6211900847a247cdaad753c.1479398226.git.jpoimboe@redhat.com/T/#u
Re: [PATCH -next] x86: Prevent KASAN false positive warnings in __show_regs()
Posted by Tengda Wu 1 month, 1 week ago
On 2025/8/21 11:13, Tengda Wu wrote:
> 
> 
> On 2025/8/21 5:36, Dave Hansen wrote:
>> On 8/18/25 06:07, Tengda Wu wrote:
>>> When process A accesses process B's `regs` from stack memory through
>>> __show_regs(), the stack of process B keeps changing during runtime.
>>> This causes false positives like "stack out-of-bounds" [1] or
>>> "out-of-bounds" [2] warnings when reading `regs` contents.
>>
>> Could you explain a little bit more how you know that these are false
>> positives?
> 
> Thanks for the question. We believe this is a false positive caused by a
> race condition during asynchronous stack tracing of a running process:
> 
> Process A (stack trace all processes)         Process 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 data pointed by
>                                                  `regs` keeps changing, and
>                                                  so are the markings in its
>                                                  KASAN shadow region.
>     __show_regs(regs)
>       regs->ax, regs->bx, ...
>         3. hit KASAN redzones, OOB
> 
> When process A stacks process B without suspending it, the continuous
> changes in process B's stack (and corresponding KASAN shadow markings)
> may cause process A to hit KASAN redzones when accessing obsolete `regs`
> addresses, resulting in false positive reports.
> 
> A sample error log for this scenario is shown below:
> 
> [332706.551830] task:cat             state:R  running task     stack:0     pid:3983623 ppid:3977902 flags:0x00004002
> [332706.551847] Call Trace:
> [332706.551853]  <TASK>
> [332706.551860]  __schedule+0x809/0x1050
> [332706.551873]  ? __pfx___schedule+0x10/0x10
> [332706.551885]  ? __stack_depot_save+0x34/0x340
> [332706.551899]  schedule+0x82/0x160
> [332706.551911]  io_schedule+0x68/0xa0
> [332706.551923]  __folio_lock_killable+0x1db/0x410
> [332706.551940]  ? __pfx___folio_lock_killable+0x10/0x10
> [332706.551955]  ? __pfx_wake_page_function+0x10/0x10
> [332706.551969]  ? __filemap_get_folio+0x4b/0x3d0
> [332706.551982]  filemap_fault+0x67a/0xbd0
> [332706.551996]  ? __pfx_filemap_fault+0x10/0x10
> [332706.552008]  ? policy_node+0x8a/0xa0
> [332706.552021]  ? __mod_node_page_state+0x23/0xf0
> [332706.552035]  __do_fault+0x6d/0x340
> [332706.552048]  do_cow_fault+0xdd/0x300
> [332706.552061]  do_fault+0x141/0x1e0
> [332706.552074]  __handle_mm_fault+0x839/0xa70
> [332706.552089]  ? __pfx___handle_mm_fault+0x10/0x10
> [332706.552105]  ? find_vma+0x6a/0x90
> [332706.552117]  handle_mm_fault+0x27d/0x470
> [332706.552132]  exc_page_fault+0x336/0x6d0
> [332706.552145]  asm_exc_page_fault+0x22/0x30
> [332706.552157] RIP: 0010:rep_stos_alternative+0x40/0x80                                         --- (1)
> [332706.552173] Code: Unable to access opcode bytes at 0x7ffe929c4fd6.                           --- (2)
> [332706.552181] RSP: 3fa6:ffff88ba5e554200 EFLAGS: ffffffff9d50c0e0 ORIG_RAX: ffff88ba5e554200   --- (3)
> [332706.552195] ==================================================================
> [332706.552324] BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340                              --- (4)
> [332706.552433] Read of size 8 at addr ffff88d24999fb20 by task sysrq_t_test.sh/3977032
> 
> We focus on logs (1) to (4):
>  * Log (1) shows the current regs->ip (a kernel-mode address);
>  * Log (2) displays regs->ip - PROLOGUE_SIZE, which deviates significantly
>    from kernel-mode addresses, indicating regs->ip has changed.
>  * Log (3) then reveals anomalous values in regs->{ss,sp,flags}.
>  * Finally, Log (4) reports a KASAN OOB error when accessing regs->bx.
> 
> Stack tracing a running task cannot guarantee the accuracy of the printed
> regs values, but accessing regs addresses does not cause kernel instability.
> Similar cases have been consistently handled this way in the past. [1][2]
> We therefore consider this a KASAN false positive.
> 
> [1] https://lore.kernel.org/all/20220915150417.722975-40-glider@google.com/T/#u
> [2] https://lore.kernel.org/all/5f6e80c4b0c7f7f0b6211900847a247cdaad753c.1479398226.git.jpoimboe@redhat.com/T/#u

Gentle ping. 
Any comment or suggestion is appreciated.

Thanks,
Tengda