unwind_frame.c (900742d89c1b4e04bd373aec8470b88e183f08ca) unwind_frame.c (84936118bdf37bda513d4a361c38181a216427e0)
1#include <linux/sched.h>
2#include <asm/ptrace.h>
3#include <asm/bitops.h>
4#include <asm/stacktrace.h>
5#include <asm/unwind.h>
6
7#define FRAME_HEADER_SIZE (sizeof(long) * 2)
8
1#include <linux/sched.h>
2#include <asm/ptrace.h>
3#include <asm/bitops.h>
4#include <asm/stacktrace.h>
5#include <asm/unwind.h>
6
7#define FRAME_HEADER_SIZE (sizeof(long) * 2)
8
9/*
10 * This disables KASAN checking when reading a value from another task's stack,
11 * since the other task could be running on another CPU and could have poisoned
12 * the stack in the meantime.
13 */
14#define READ_ONCE_TASK_STACK(task, x) \
15({ \
16 unsigned long val; \
17 if (task == current) \
18 val = READ_ONCE(x); \
19 else \
20 val = READ_ONCE_NOCHECK(x); \
21 val; \
22})
23
9static void unwind_dump(struct unwind_state *state, unsigned long *sp)
10{
11 static bool dumped_before = false;
12 bool prev_zero, zero = false;
13 unsigned long word;
14
15 if (dumped_before)
16 return;

--- 26 unchanged lines hidden (view full) ---

43 unsigned long *addr_p = unwind_get_return_address_ptr(state);
44
45 if (unwind_done(state))
46 return 0;
47
48 if (state->regs && user_mode(state->regs))
49 return 0;
50
24static void unwind_dump(struct unwind_state *state, unsigned long *sp)
25{
26 static bool dumped_before = false;
27 bool prev_zero, zero = false;
28 unsigned long word;
29
30 if (dumped_before)
31 return;

--- 26 unchanged lines hidden (view full) ---

58 unsigned long *addr_p = unwind_get_return_address_ptr(state);
59
60 if (unwind_done(state))
61 return 0;
62
63 if (state->regs && user_mode(state->regs))
64 return 0;
65
51 addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p,
66 addr = READ_ONCE_TASK_STACK(state->task, *addr_p);
67 addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, addr,
52 addr_p);
53
54 return __kernel_text_address(addr) ? addr : 0;
55}
56EXPORT_SYMBOL_GPL(unwind_get_return_address);
57
58static size_t regs_size(struct pt_regs *regs)
59{

--- 97 unchanged lines hidden (view full) ---

157 state->bp = NULL;
158 return true;
159 }
160
161 /* get the next frame pointer */
162 if (state->regs)
163 next_bp = (unsigned long *)state->regs->bp;
164 else
68 addr_p);
69
70 return __kernel_text_address(addr) ? addr : 0;
71}
72EXPORT_SYMBOL_GPL(unwind_get_return_address);
73
74static size_t regs_size(struct pt_regs *regs)
75{

--- 97 unchanged lines hidden (view full) ---

173 state->bp = NULL;
174 return true;
175 }
176
177 /* get the next frame pointer */
178 if (state->regs)
179 next_bp = (unsigned long *)state->regs->bp;
180 else
165 next_bp = (unsigned long *)*state->bp;
181 next_bp = (unsigned long *)READ_ONCE_TASK_STACK(state->task,*state->bp);
166
167 /* is the next frame pointer an encoded pointer to pt_regs? */
168 regs = decode_frame_pointer(next_bp);
169 if (regs) {
170 next_frame = (unsigned long *)regs;
171 next_len = sizeof(*regs);
172 } else {
173 next_frame = next_bp;

--- 109 unchanged lines hidden ---
182
183 /* is the next frame pointer an encoded pointer to pt_regs? */
184 regs = decode_frame_pointer(next_bp);
185 if (regs) {
186 next_frame = (unsigned long *)regs;
187 next_len = sizeof(*regs);
188 } else {
189 next_frame = next_bp;

--- 109 unchanged lines hidden ---