|
45 | 45 | #define CREATE_TRACE_POINTS
|
46 | 46 | #include <trace/events/syscalls.h>
|
47 | 47 |
|
| 48 | +/* Check that the stack and regs on entry from user mode are sane. */ |
| 49 | +static void check_user_regs(struct pt_regs *regs) |
| 50 | +{ |
| 51 | + if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) { |
| 52 | + WARN_ON_ONCE(!on_thread_stack()); |
| 53 | + WARN_ON_ONCE(regs != task_pt_regs(current)); |
| 54 | + } |
| 55 | +} |
| 56 | + |
48 | 57 | #ifdef CONFIG_CONTEXT_TRACKING
|
49 | 58 | /**
|
50 | 59 | * enter_from_user_mode - Establish state when coming from user mode
|
@@ -127,9 +136,6 @@ static long syscall_trace_enter(struct pt_regs *regs)
|
127 | 136 | unsigned long ret = 0;
|
128 | 137 | u32 work;
|
129 | 138 |
|
130 |
| - if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) |
131 |
| - BUG_ON(regs != task_pt_regs(current)); |
132 |
| - |
133 | 139 | work = READ_ONCE(ti->flags);
|
134 | 140 |
|
135 | 141 | if (work & (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU)) {
|
@@ -346,6 +352,8 @@ __visible noinstr void do_syscall_64(unsigned long nr, struct pt_regs *regs)
|
346 | 352 | {
|
347 | 353 | struct thread_info *ti;
|
348 | 354 |
|
| 355 | + check_user_regs(regs); |
| 356 | + |
349 | 357 | enter_from_user_mode();
|
350 | 358 | instrumentation_begin();
|
351 | 359 |
|
@@ -409,6 +417,8 @@ static void do_syscall_32_irqs_on(struct pt_regs *regs)
|
409 | 417 | /* Handles int $0x80 */
|
410 | 418 | __visible noinstr void do_int80_syscall_32(struct pt_regs *regs)
|
411 | 419 | {
|
| 420 | + check_user_regs(regs); |
| 421 | + |
412 | 422 | enter_from_user_mode();
|
413 | 423 | instrumentation_begin();
|
414 | 424 |
|
@@ -460,6 +470,8 @@ __visible noinstr long do_fast_syscall_32(struct pt_regs *regs)
|
460 | 470 | vdso_image_32.sym_int80_landing_pad;
|
461 | 471 | bool success;
|
462 | 472 |
|
| 473 | + check_user_regs(regs); |
| 474 | + |
463 | 475 | /*
|
464 | 476 | * SYSENTER loses EIP, and even SYSCALL32 needs us to skip forward
|
465 | 477 | * so that 'regs->ip -= 2' lands back on an int $0x80 instruction.
|
|
0 commit comments