| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | #include <linux/sched.h> |
|---|
| 2 | 3 | #include <linux/sched/task.h> |
|---|
| 3 | 4 | #include <linux/sched/task_stack.h> |
|---|
| .. | .. |
|---|
| 69 | 70 | } |
|---|
| 70 | 71 | } |
|---|
| 71 | 72 | |
|---|
| 72 | | -static size_t regs_size(struct pt_regs *regs) |
|---|
| 73 | | -{ |
|---|
| 74 | | - /* x86_32 regs from kernel mode are two words shorter: */ |
|---|
| 75 | | - if (IS_ENABLED(CONFIG_X86_32) && !user_mode(regs)) |
|---|
| 76 | | - return sizeof(*regs) - 2*sizeof(long); |
|---|
| 77 | | - |
|---|
| 78 | | - return sizeof(*regs); |
|---|
| 79 | | -} |
|---|
| 80 | | - |
|---|
| 81 | 73 | static bool in_entry_code(unsigned long ip) |
|---|
| 82 | 74 | { |
|---|
| 83 | 75 | char *addr = (char *)ip; |
|---|
| 84 | 76 | |
|---|
| 85 | | - if (addr >= __entry_text_start && addr < __entry_text_end) |
|---|
| 86 | | - return true; |
|---|
| 87 | | - |
|---|
| 88 | | - if (addr >= __irqentry_text_start && addr < __irqentry_text_end) |
|---|
| 89 | | - return true; |
|---|
| 90 | | - |
|---|
| 91 | | - return false; |
|---|
| 77 | + return addr >= __entry_text_start && addr < __entry_text_end; |
|---|
| 92 | 78 | } |
|---|
| 93 | 79 | |
|---|
| 94 | 80 | static inline unsigned long *last_frame(struct unwind_state *state) |
|---|
| .. | .. |
|---|
| 197 | 183 | } |
|---|
| 198 | 184 | #endif |
|---|
| 199 | 185 | |
|---|
| 200 | | -#ifdef CONFIG_X86_32 |
|---|
| 201 | | -#define KERNEL_REGS_SIZE (sizeof(struct pt_regs) - 2*sizeof(long)) |
|---|
| 202 | | -#else |
|---|
| 203 | | -#define KERNEL_REGS_SIZE (sizeof(struct pt_regs)) |
|---|
| 204 | | -#endif |
|---|
| 205 | | - |
|---|
| 206 | 186 | static bool update_stack_state(struct unwind_state *state, |
|---|
| 207 | 187 | unsigned long *next_bp) |
|---|
| 208 | 188 | { |
|---|
| .. | .. |
|---|
| 213 | 193 | size_t len; |
|---|
| 214 | 194 | |
|---|
| 215 | 195 | if (state->regs) |
|---|
| 216 | | - prev_frame_end = (void *)state->regs + regs_size(state->regs); |
|---|
| 196 | + prev_frame_end = (void *)state->regs + sizeof(*state->regs); |
|---|
| 217 | 197 | else |
|---|
| 218 | 198 | prev_frame_end = (void *)state->bp + FRAME_HEADER_SIZE; |
|---|
| 219 | 199 | |
|---|
| .. | .. |
|---|
| 221 | 201 | regs = decode_frame_pointer(next_bp); |
|---|
| 222 | 202 | if (regs) { |
|---|
| 223 | 203 | frame = (unsigned long *)regs; |
|---|
| 224 | | - len = KERNEL_REGS_SIZE; |
|---|
| 204 | + len = sizeof(*regs); |
|---|
| 225 | 205 | state->got_irq = true; |
|---|
| 226 | 206 | } else { |
|---|
| 227 | 207 | frame = next_bp; |
|---|
| .. | .. |
|---|
| 243 | 223 | /* Make sure it only unwinds up and doesn't overlap the prev frame: */ |
|---|
| 244 | 224 | if (state->orig_sp && state->stack_info.type == prev_type && |
|---|
| 245 | 225 | frame < prev_frame_end) |
|---|
| 246 | | - return false; |
|---|
| 247 | | - |
|---|
| 248 | | - /* |
|---|
| 249 | | - * On 32-bit with user mode regs, make sure the last two regs are safe |
|---|
| 250 | | - * to access: |
|---|
| 251 | | - */ |
|---|
| 252 | | - if (IS_ENABLED(CONFIG_X86_32) && regs && user_mode(regs) && |
|---|
| 253 | | - !on_stack(info, frame, len + 2*sizeof(long))) |
|---|
| 254 | 226 | return false; |
|---|
| 255 | 227 | |
|---|
| 256 | 228 | /* Move state to the next frame: */ |
|---|
| .. | .. |
|---|
| 297 | 269 | /* |
|---|
| 298 | 270 | * kthreads (other than the boot CPU's idle thread) have some |
|---|
| 299 | 271 | * partial regs at the end of their stack which were placed |
|---|
| 300 | | - * there by copy_thread_tls(). But the regs don't have any |
|---|
| 272 | + * there by copy_thread(). But the regs don't have any |
|---|
| 301 | 273 | * useful information, so we can skip them. |
|---|
| 302 | 274 | * |
|---|
| 303 | 275 | * This user_mode() check is slightly broader than a PF_KTHREAD |
|---|
| 304 | 276 | * check because it also catches the awkward situation where a |
|---|
| 305 | 277 | * newly forked kthread transitions into a user task by calling |
|---|
| 306 | | - * do_execve(), which eventually clears PF_KTHREAD. |
|---|
| 278 | + * kernel_execve(), which eventually clears PF_KTHREAD. |
|---|
| 307 | 279 | */ |
|---|
| 308 | 280 | if (!user_mode(regs)) |
|---|
| 309 | 281 | goto the_end; |
|---|
| .. | .. |
|---|
| 366 | 338 | if (IS_ENABLED(CONFIG_X86_32)) |
|---|
| 367 | 339 | goto the_end; |
|---|
| 368 | 340 | |
|---|
| 341 | + if (state->task != current) |
|---|
| 342 | + goto the_end; |
|---|
| 343 | + |
|---|
| 369 | 344 | if (state->regs) { |
|---|
| 370 | 345 | printk_deferred_once(KERN_WARNING |
|---|
| 371 | 346 | "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n", |
|---|
| .. | .. |
|---|
| 411 | 386 | * Pretend that the frame is complete and that BP points to it, but save |
|---|
| 412 | 387 | * the real BP so that we can use it when looking for the next frame. |
|---|
| 413 | 388 | */ |
|---|
| 414 | | - if (regs && regs->ip == 0 && |
|---|
| 415 | | - (unsigned long *)kernel_stack_pointer(regs) >= first_frame) { |
|---|
| 389 | + if (regs && regs->ip == 0 && (unsigned long *)regs->sp >= first_frame) { |
|---|
| 416 | 390 | state->next_bp = bp; |
|---|
| 417 | | - bp = ((unsigned long *)kernel_stack_pointer(regs)) - 1; |
|---|
| 391 | + bp = ((unsigned long *)regs->sp) - 1; |
|---|
| 418 | 392 | } |
|---|
| 419 | 393 | |
|---|
| 420 | 394 | /* Initialize stack info and make sure the frame data is accessible: */ |
|---|