]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
s390/ptrace: Avoid KASAN false positives in regs_get_kernel_stack_nth()
authorVasily Gorbik <gor@linux.ibm.com>
Thu, 6 Mar 2025 18:12:54 +0000 (19:12 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 18 Mar 2025 16:13:05 +0000 (17:13 +0100)
With recent ftrace changes, argument tracing has been added to the
function tracer. As a result, ftrace opportunistically reads the first
FTRACE_REGS_MAX_ARGS (i.e., 6) registers. On s390, only five arguments are
passed in registers, and the 6-th is read from the stack. If a function
has fewer than 6 arguments, the following KASAN report may be observed:

 BUG: KASAN: stack-out-of-bounds in regs_get_kernel_stack_nth+0xa8/0xb0
 Read of size 8 at addr 00007f7fe066fdb8 by task swapper/31/0

 CPU: 31 UID: 0 PID: 0 Comm: swapper/31 Not tainted 6.14.0-rc4-00006-g76fe0337c219 #16
 Hardware name: IBM 3931 A01 704 (KVM/Linux)
 Call Trace:
  [<00007fffe0147224>] dump_stack_lvl+0x104/0x168
  [<00007fffe011381c>] print_address_description.constprop.0+0x34/0x338
  [<00007fffe0113b64>] print_report+0x44/0x138
  [<00007fffe0ad9422>] kasan_report+0xc2/0x180
  [<00007fffe0159ff8>] regs_get_kernel_stack_nth+0xa8/0xb0
  [<00007fffe05ebeda>] trace_function+0x23a/0x4d0
  [<00007fffe0615d32>] irqsoff_tracer_call+0xd2/0x110
  [<00007fffe2b4e34c>] ftrace_common+0x1c/0x40
  [<00007fffe0150826>] arch_cpu_idle_enter+0x6/0x10
  [<00007fffe035a1c8>] do_idle+0x168/0x2e0
  [<00007fffe035a9d0>] cpu_startup_entry+0x90/0xb0
  [<00007fffe017d25a>] smp_start_secondary+0x3da/0x4e0
  [<00007fffe2b4e20a>] restart_int_handler+0x72/0x88
 no locks held by swapper/31/0.

 The buggy address belongs to stack of task swapper/31/0
  and is located at offset 0 in frame:
  do_idle+0x0/0x2e0

 This frame has 1 object:
  [32, 40) '__mask'

 The buggy address belongs to the virtual mapping at
  [00007f7fe066000000007f7fe0671000) created by:
  dup_task_struct+0x66/0x4e0

 The buggy address belongs to the physical page:
 page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x80f23
 flags: 0x3ffff00000000000(node=0|zone=1|lastcpupid=0x1ffff)
 raw: 3ffff00000000000 0000000000000000 0000000000000122 0000000000000000
 raw: 0000000000000000 0000000000000000 ffffffff00000001 0000000000000000
 page dumped because: kasan: bad access detected

 Memory state around the buggy address:
  00007f7fe066fc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  00007f7fe066fd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 >00007f7fe066fd80: 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f3 f3 f3 00
                                         ^
  00007f7fe066fe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  00007f7fe066fe80: 00 f1 f1 f1 f1 00 f2 f2 f2 00 00 f3 f3 00 00 00

The function regs_get_kernel_stack_nth() verifies that the requested
argument is located on the stack, making it safe to read even if it is
not actually present. Make use of READ_ONCE_NOCHECK() helper to silence
KASAN reports in this case.

Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/kernel/ptrace.c

index 6f2ae0be22982573721769741548592424ab7c35..34b8d9e745df0588c62a4ee01ba8b7db76b54561 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/facility.h>
 #include <asm/machine.h>
 #include <asm/ptrace.h>
+#include <asm/rwonce.h>
 #include <asm/fpu.h>
 
 #include "entry.h"
@@ -1573,5 +1574,5 @@ unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
        addr = kernel_stack_pointer(regs) + n * sizeof(long);
        if (!regs_within_kernel_stack(regs, addr))
                return 0;
-       return *(unsigned long *)addr;
+       return READ_ONCE_NOCHECK(addr);
 }