History

Merge tag 'x86-urgent-2020-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into master

Pull x86 fixes from Ingo Molnar: "Misc fixes: - Fix a section end page alignment assumption that was causing crashes - Fix ORC unwinding on freshly forked tasks which haven't executed yet and which have empty user task stacks - Fix the debug.exception-trace=1 sysctl dumping of user stacks, which was broken by recent maccess changes" * tag 'x86-urgent-2020-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/dumpstack: Dump user space code correctly again x86/stacktrace: Fix reliable check for empty user task stacks x86/unwind/orc: Fix ORC for newly forked tasks x86, vmlinux.lds: Page-align end of ..page_aligned sections

Linus Torvalds committed 6 years ago

Commit fbe0d452 parents 78b1afe d181d2d5 files · +28 −18Browse files

Unified · Split

5 files
  1. arch/x86/kernel/dumpstack.c +17 −10
  2. arch/x86/kernel/stacktrace.c +0 −5
  3. arch/x86/kernel/unwind_orc.c +6 −2
  4. arch/x86/kernel/vmlinux.lds.S +1 −0
  5. include/asm-generic/vmlinux.lds.h +4 −1
arch/x86/kernel/dumpstack.c+17−10
@@ -71,6 +71,22 @@ static void printk_stack_address(unsigned long address, int reliable, · 70 unmodified lines
71 printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address);71 printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address);
72}72}
73 73
74static int copy_code(struct pt_regs *regs, u8 *buf, unsigned long src,
75 unsigned int nbytes)
76{
77 if (!user_mode(regs))
78 return copy_from_kernel_nofault(buf, (u8 *)src, nbytes);
79
80 /*
81 * Make sure userspace isn't trying to trick us into dumping kernel
82 * memory by pointing the userspace instruction pointer at it.
83 */
84 if (__chk_range_not_ok(src, nbytes, TASK_SIZE_MAX))
85 return -EINVAL;
86
87 return copy_from_user_nmi(buf, (void __user *)src, nbytes);
88}
89
74/*90/*
75 * There are a couple of reasons for the 2/3rd prologue, courtesy of Linus:91 * There are a couple of reasons for the 2/3rd prologue, courtesy of Linus:
76 *92 *
@@ -97,17 +113,8 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl) · 20 unmodified lines
97#define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE)113#define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE)
98 u8 opcodes[OPCODE_BUFSIZE];114 u8 opcodes[OPCODE_BUFSIZE];
99 unsigned long prologue = regs->ip - PROLOGUE_SIZE;115 unsigned long prologue = regs->ip - PROLOGUE_SIZE;
100 bool bad_ip;
101
102 /*
103 * Make sure userspace isn't trying to trick us into dumping kernel
104 * memory by pointing the userspace instruction pointer at it.
105 */
106 bad_ip = user_mode(regs) &&
107 __chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX);
108 116
109 if (bad_ip || copy_from_kernel_nofault(opcodes, (u8 *)prologue,117 if (copy_code(regs, opcodes, prologue, sizeof(opcodes))) {
110 OPCODE_BUFSIZE)) {
111 printk("%sCode: Bad RIP value.\n", loglvl);118 printk("%sCode: Bad RIP value.\n", loglvl);
112 } else {119 } else {
113 printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %"120 printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %"
arch/x86/kernel/stacktrace.c+0−5
@@ -58,7 +58,6 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, · 57 unmodified lines
58 * or a page fault), which can make frame pointers58 * or a page fault), which can make frame pointers
59 * unreliable.59 * unreliable.
60 */60 */
61
62 if (IS_ENABLED(CONFIG_FRAME_POINTER))61 if (IS_ENABLED(CONFIG_FRAME_POINTER))
63 return -EINVAL;62 return -EINVAL;
64 }63 }
@@ -81,10 +80,6 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, · 16 unmodified lines
81 if (unwind_error(&state))80 if (unwind_error(&state))
82 return -EINVAL;81 return -EINVAL;
83 82
84 /* Success path for non-user tasks, i.e. kthreads and idle tasks */
85 if (!(task->flags & (PF_KTHREAD | PF_IDLE)))
86 return -EINVAL;
87
88 return 0;83 return 0;
89}84}
90 85
arch/x86/kernel/unwind_orc.c+6−2
@@ -440,8 +440,11 @@ bool unwind_next_frame(struct unwind_state *state) · 439 unmodified lines
440 /*440 /*
441 * Find the orc_entry associated with the text address.441 * Find the orc_entry associated with the text address.
442 *442 *
443 * Decrement call return addresses by one so they work for sibling443 * For a call frame (as opposed to a signal frame), state->ip points to
444 * calls and calls to noreturn functions.444 * the instruction after the call. That instruction's stack layout
445 * could be different from the call instruction's layout, for example
446 * if the call was to a noreturn function. So get the ORC data for the
447 * call instruction itself.
445 */448 */
446 orc = orc_find(state->signal ? state->ip : state->ip - 1);449 orc = orc_find(state->signal ? state->ip : state->ip - 1);
447 if (!orc) {450 if (!orc) {
@@ -662,6 +665,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, · 214 unmodified lines
662 state->sp = task->thread.sp;665 state->sp = task->thread.sp;
663 state->bp = READ_ONCE_NOCHECK(frame->bp);666 state->bp = READ_ONCE_NOCHECK(frame->bp);
664 state->ip = READ_ONCE_NOCHECK(frame->ret_addr);667 state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
668 state->signal = (void *)state->ip == ret_from_fork;
665 }669 }
666 670
667 if (get_stack_info((unsigned long *)state->sp, state->task,671 if (get_stack_info((unsigned long *)state->sp, state->task,
arch/x86/kernel/vmlinux.lds.S+1−0
@@ -358,6 +358,7 @@ SECTIONS · 357 unmodified lines
358 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {358 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
359 __bss_start = .;359 __bss_start = .;
360 *(.bss..page_aligned)360 *(.bss..page_aligned)
361 . = ALIGN(PAGE_SIZE);
361 *(BSS_MAIN)362 *(BSS_MAIN)
362 BSS_DECRYPTED363 BSS_DECRYPTED
363 . = ALIGN(PAGE_SIZE);364 . = ALIGN(PAGE_SIZE);
include/asm-generic/vmlinux.lds.h+4−1
@@ -341,7 +341,8 @@ · 340 unmodified lines
341 341
342#define PAGE_ALIGNED_DATA(page_align) \342#define PAGE_ALIGNED_DATA(page_align) \
343 . = ALIGN(page_align); \343 . = ALIGN(page_align); \
344 *(.data..page_aligned)344 *(.data..page_aligned) \
345 . = ALIGN(page_align);
345 346
346#define READ_MOSTLY_DATA(align) \347#define READ_MOSTLY_DATA(align) \
347 . = ALIGN(align); \348 . = ALIGN(align); \
@@ -737,7 +738,9 @@ · 389 unmodified lines
737 . = ALIGN(bss_align); \738 . = ALIGN(bss_align); \
738 .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \739 .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \
739 BSS_FIRST_SECTIONS \740 BSS_FIRST_SECTIONS \
741 . = ALIGN(PAGE_SIZE); \
740 *(.bss..page_aligned) \742 *(.bss..page_aligned) \
743 . = ALIGN(PAGE_SIZE); \
741 *(.dynbss) \744 *(.dynbss) \
742 *(BSS_MAIN) \745 *(BSS_MAIN) \
743 *(COMMON) \746 *(COMMON) \