1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Stack trace management functions |
4 | * |
5 | * Copyright IBM Corp. 2006 |
6 | */ |
7 | |
8 | #include <linux/stacktrace.h> |
9 | #include <linux/uaccess.h> |
10 | #include <linux/compat.h> |
11 | #include <asm/stacktrace.h> |
12 | #include <asm/unwind.h> |
13 | #include <asm/kprobes.h> |
14 | #include <asm/ptrace.h> |
15 | |
16 | void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, |
17 | struct task_struct *task, struct pt_regs *regs) |
18 | { |
19 | struct unwind_state state; |
20 | unsigned long addr; |
21 | |
22 | unwind_for_each_frame(&state, task, regs, 0) { |
23 | addr = unwind_get_return_address(state: &state); |
24 | if (!addr || !consume_entry(cookie, addr)) |
25 | break; |
26 | } |
27 | } |
28 | |
29 | int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, |
30 | void *cookie, struct task_struct *task) |
31 | { |
32 | struct unwind_state state; |
33 | unsigned long addr; |
34 | |
35 | unwind_for_each_frame(&state, task, NULL, 0) { |
36 | if (state.stack_info.type != STACK_TYPE_TASK) |
37 | return -EINVAL; |
38 | |
39 | if (state.regs) |
40 | return -EINVAL; |
41 | |
42 | addr = unwind_get_return_address(state: &state); |
43 | if (!addr) |
44 | return -EINVAL; |
45 | |
46 | #ifdef CONFIG_RETHOOK |
47 | /* |
48 | * Mark stacktraces with krethook functions on them |
49 | * as unreliable. |
50 | */ |
51 | if (state.ip == (unsigned long)arch_rethook_trampoline) |
52 | return -EINVAL; |
53 | #endif |
54 | |
55 | if (!consume_entry(cookie, addr)) |
56 | return -EINVAL; |
57 | } |
58 | |
59 | /* Check for stack corruption */ |
60 | if (unwind_error(state: &state)) |
61 | return -EINVAL; |
62 | return 0; |
63 | } |
64 | |
65 | void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie, |
66 | const struct pt_regs *regs) |
67 | { |
68 | struct stack_frame_user __user *sf; |
69 | unsigned long ip, sp; |
70 | bool first = true; |
71 | |
72 | if (is_compat_task()) |
73 | return; |
74 | if (!consume_entry(cookie, instruction_pointer(regs))) |
75 | return; |
76 | sf = (void __user *)user_stack_pointer(regs); |
77 | pagefault_disable(); |
78 | while (1) { |
79 | if (__get_user(sp, &sf->back_chain)) |
80 | break; |
81 | if (__get_user(ip, &sf->gprs[8])) |
82 | break; |
83 | if (ip & 0x1) { |
84 | /* |
85 | * If the instruction address is invalid, and this |
86 | * is the first stack frame, assume r14 has not |
87 | * been written to the stack yet. Otherwise exit. |
88 | */ |
89 | if (first && !(regs->gprs[14] & 0x1)) |
90 | ip = regs->gprs[14]; |
91 | else |
92 | break; |
93 | } |
94 | if (!consume_entry(cookie, ip)) |
95 | break; |
96 | /* Sanity check: ABI requires SP to be aligned 8 bytes. */ |
97 | if (!sp || sp & 0x7) |
98 | break; |
99 | sf = (void __user *)sp; |
100 | first = false; |
101 | } |
102 | pagefault_enable(); |
103 | } |
104 | |