bianbu-linux-6.6/arch/riscv/kernel/stacktrace.c
lijuan cce016473f stacktrace: delect KASAN warning
2024-10-26T17:47:08.370644+08:00 M1-MUSE-BOOK kernel: BUG: KASAN: stack-out-of-bounds in walk_stackframe+0x27a/0x2ec
2024-10-26T17:47:08.370735+08:00 M1-MUSE-BOOK kernel: Read of size 8 at addr ffffffc8121f3b88 by task gnome-system-mo/29287
2024-10-26T17:47:08.370758+08:00 M1-MUSE-BOOK kernel:
2024-10-26T17:47:08.370770+08:00 M1-MUSE-BOOK kernel: CPU: 1 PID: 29287 Comm: gnome-system-mo Tainted: G        W          6.6.36 #20241025175156
2024-10-26T17:47:08.370782+08:00 M1-MUSE-BOOK kernel: Hardware name: M1-MUSE-BOOK (DT)
2024-10-26T17:47:08.370795+08:00 M1-MUSE-BOOK kernel: Call Trace:
2024-10-26T17:47:08.370806+08:00 M1-MUSE-BOOK kernel: [<ffffffff8000cd28>] dump_backtrace+0x1c/0x24
2024-10-26T17:47:08.370812+08:00 M1-MUSE-BOOK kernel: [<ffffffff82fa48a8>] show_stack+0x2c/0x38
2024-10-26T17:47:08.370820+08:00 M1-MUSE-BOOK kernel: [<ffffffff82fe1d6e>] dump_stack_lvl+0x3c/0x54
2024-10-26T17:47:08.370828+08:00 M1-MUSE-BOOK kernel: [<ffffffff82fac564>] print_report+0x19e/0x4b4
2024-10-26T17:47:08.370838+08:00 M1-MUSE-BOOK kernel: [<ffffffff8062b218>] kasan_report+0xbc/0x170
2024-10-26T17:47:08.370847+08:00 M1-MUSE-BOOK kernel: [<ffffffff8062cb3e>] __asan_report_load8_noabort+0x12/0x1a
2024-10-26T17:47:08.370853+08:00 M1-MUSE-BOOK kernel: [<ffffffff8000cc42>] walk_stackframe+0x27a/0x2ec
2024-10-26T17:47:08.370861+08:00 M1-MUSE-BOOK kernel: [<ffffffff8000ce6c>] __get_wchan+0x13c/0x1c2
2024-10-26T17:47:08.370871+08:00 M1-MUSE-BOOK kernel: [<ffffffff800d905c>] get_wchan+0x86/0xd6
2024-10-26T17:47:08.370880+08:00 M1-MUSE-BOOK kernel: [<ffffffff808124e0>] proc_pid_wchan+0xea/0x112
2024-10-26T17:47:08.370889+08:00 M1-MUSE-BOOK kernel: [<ffffffff808146d4>] proc_single_show+0xdc/0x1b0
2024-10-26T17:47:08.370895+08:00 M1-MUSE-BOOK kernel: [<ffffffff8070a1b0>] seq_read_iter+0x26c/0xcf4
2024-10-26T17:47:08.370901+08:00 M1-MUSE-BOOK kernel: [<ffffffff8070ad58>] seq_read+0x120/0x19c
2024-10-26T17:47:08.370909+08:00 M1-MUSE-BOOK kernel: [<ffffffff8069467a>] vfs_read+0x20c/0x644
2024-10-26T17:47:08.370917+08:00 M1-MUSE-BOOK kernel: [<ffffffff8069646c>] ksys_read+0xe2/0x1aa
2024-10-26T17:47:08.370924+08:00 M1-MUSE-BOOK kernel: [<ffffffff8069659a>] __riscv_sys_read+0x66/0x8c
2024-10-26T17:47:08.370931+08:00 M1-MUSE-BOOK kernel: [<ffffffff8000bf26>] syscall_handler+0x64/0xf0
2024-10-26T17:47:08.370938+08:00 M1-MUSE-BOOK kernel: [<ffffffff82fe2460>] do_trap_ecall_u+0x9c/0x9e
2024-10-26T17:47:08.370944+08:00 M1-MUSE-BOOK kernel: [<ffffffff83001df6>] ret_from_exception+0x0/0x6e
2024-10-26T17:47:08.370951+08:00 M1-MUSE-BOOK kernel:
2024-10-26T17:47:08.370959+08:00 M1-MUSE-BOOK kernel: The buggy address belongs to the virtual mapping at
2024-10-26T17:47:08.370965+08:00 M1-MUSE-BOOK kernel:  [ffffffc8121f0000, ffffffc8121f5000) created by:
2024-10-26T17:47:08.370973+08:00 M1-MUSE-BOOK kernel:  kernel_clone+0xaa/0x8ac
2024-10-26T17:47:08.370980+08:00 M1-MUSE-BOOK kernel:
2024-10-26T17:47:08.370987+08:00 M1-MUSE-BOOK kernel: The buggy address belongs to the physical page:
2024-10-26T17:47:08.370995+08:00 M1-MUSE-BOOK kernel: page:0000000053006164 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x222afe
2024-10-26T17:47:08.371003+08:00 M1-MUSE-BOOK kernel: memcg:ffffffd926967782
2024-10-26T17:47:08.371184+08:00 M1-MUSE-BOOK kernel: flags: 0x4000000000000000(zone=1)
2024-10-26T17:47:08.371245+08:00 M1-MUSE-BOOK kernel: page_type: 0xffffffff()
2024-10-26T17:47:08.371269+08:00 M1-MUSE-BOOK kernel: raw: 4000000000000000 0000000000000000 0000000000000122 0000000000000000
2024-10-26T17:47:08.371281+08:00 M1-MUSE-BOOK kernel: raw: 0000000000000000 0000000000000000 00000001ffffffff ffffffd926967782
2024-10-26T17:47:08.371293+08:00 M1-MUSE-BOOK kernel: page dumped because: kasan: bad access detected
2024-10-26T17:47:08.371301+08:00 M1-MUSE-BOOK kernel:
2024-10-26T17:47:08.371308+08:00 M1-MUSE-BOOK kernel: Memory state around the buggy address:
2024-10-26T17:47:08.371315+08:00 M1-MUSE-BOOK kernel:  ffffffc8121f3a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2024-10-26T17:47:08.371321+08:00 M1-MUSE-BOOK kernel:  ffffffc8121f3b00: f1 f1 f1 f1 00 f2 f2 f2 00 00 00 00 00 00 00 00
2024-10-26T17:47:08.371327+08:00 M1-MUSE-BOOK kernel: >ffffffc8121f3b80: 00 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00
2024-10-26T17:47:08.371333+08:00 M1-MUSE-BOOK kernel:                       ^
2024-10-26T17:47:08.371341+08:00 M1-MUSE-BOOK kernel:  ffffffc8121f3c00: 00 00 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00
2024-10-26T17:47:08.371348+08:00 M1-MUSE-BOOK kernel:  ffffffc8121f3c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2024-10-26T17:47:08.371354+08:00 M1-MUSE-BOOK kernel: ==================================================================

Change-Id: If6d382f0551ec1b5f15c91fdb5e0e568bc674b4d
Signed-off-by: lijuan <juan.li@spacemit.com>
2024-11-28 18:29:12 +08:00

164 lines
3.7 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2008 ARM Limited
* Copyright (C) 2014 Regents of the University of California
*/
#include <linux/export.h>
#include <linux/kallsyms.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/task_stack.h>
#include <linux/stacktrace.h>
#include <linux/ftrace.h>
#include <asm/stacktrace.h>
#ifdef CONFIG_FRAME_POINTER
extern asmlinkage void ret_from_exception(void);
static inline int fp_is_valid(unsigned long fp, unsigned long sp)
{
unsigned long low, high;
low = sp + sizeof(struct stackframe);
high = ALIGN(sp, THREAD_SIZE);
return !(fp < low || fp > high || fp & 0x07);
}
void notrace __no_sanitize_address walk_stackframe(struct task_struct *task, struct pt_regs *regs,
bool (*fn)(void *, unsigned long), void *arg)
{
unsigned long fp, sp, pc;
int graph_idx = 0;
int level = 0;
if (regs) {
fp = frame_pointer(regs);
sp = user_stack_pointer(regs);
pc = instruction_pointer(regs);
} else if (task == NULL || task == current) {
fp = (unsigned long)__builtin_frame_address(0);
sp = current_stack_pointer;
pc = (unsigned long)walk_stackframe;
level = -1;
} else {
/* task blocked in __switch_to */
fp = task->thread.s[0];
sp = task->thread.sp;
pc = task->thread.ra;
}
for (;;) {
struct stackframe *frame;
if (unlikely(!__kernel_text_address(pc) || (level++ >= 0 && !fn(arg, pc))))
break;
if (unlikely(!fp_is_valid(fp, sp)))
break;
/* Unwind stack frame */
frame = (struct stackframe *)fp - 1;
sp = fp;
if (regs && (regs->epc == pc) && fp_is_valid(frame->ra, sp)) {
/* We hit function where ra is not saved on the stack */
fp = frame->ra;
pc = regs->ra;
} else {
fp = frame->fp;
pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra,
&frame->ra);
if (pc == (unsigned long)ret_from_exception) {
if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
break;
pc = ((struct pt_regs *)sp)->epc;
fp = ((struct pt_regs *)sp)->s0;
}
}
}
}
#else /* !CONFIG_FRAME_POINTER */
void notrace walk_stackframe(struct task_struct *task,
struct pt_regs *regs, bool (*fn)(void *, unsigned long), void *arg)
{
unsigned long sp, pc;
unsigned long *ksp;
if (regs) {
sp = user_stack_pointer(regs);
pc = instruction_pointer(regs);
} else if (task == NULL || task == current) {
sp = current_stack_pointer;
pc = (unsigned long)walk_stackframe;
} else {
/* task blocked in __switch_to */
sp = task->thread.sp;
pc = task->thread.ra;
}
if (unlikely(sp & 0x7))
return;
ksp = (unsigned long *)sp;
while (!kstack_end(ksp)) {
if (__kernel_text_address(pc) && unlikely(!fn(arg, pc)))
break;
pc = READ_ONCE_NOCHECK(*ksp++) - 0x4;
}
}
#endif /* CONFIG_FRAME_POINTER */
static bool print_trace_address(void *arg, unsigned long pc)
{
const char *loglvl = arg;
print_ip_sym(loglvl, pc);
return true;
}
noinline void dump_backtrace(struct pt_regs *regs, struct task_struct *task,
const char *loglvl)
{
walk_stackframe(task, regs, print_trace_address, (void *)loglvl);
}
void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
{
pr_cont("%sCall Trace:\n", loglvl);
dump_backtrace(NULL, task, loglvl);
}
static bool save_wchan(void *arg, unsigned long pc)
{
if (!in_sched_functions(pc)) {
unsigned long *p = arg;
*p = pc;
return false;
}
return true;
}
unsigned long __get_wchan(struct task_struct *task)
{
unsigned long pc = 0;
if (!try_get_task_stack(task))
return 0;
walk_stackframe(task, NULL, save_wchan, &pc);
put_task_stack(task);
return pc;
}
noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
struct task_struct *task, struct pt_regs *regs)
{
walk_stackframe(task, regs, consume_entry, cookie);
}