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
7171 printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address);
7272 }
7373
74+static 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+
7490 /*
7591 * There are a couple of reasons for the 2/3rd prologue, courtesy of Linus:
7692 *
@@ -97,17 +113,8 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl) · 20 unmodified lines
97113 #define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE)
98114 u8 opcodes[OPCODE_BUFSIZE];
99115 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);
108116
109− if (bad_ip || copy_from_kernel_nofault(opcodes, (u8 *)prologue,
110− OPCODE_BUFSIZE)) {
117+ if (copy_code(regs, opcodes, prologue, sizeof(opcodes))) {
111118 printk("%sCode: Bad RIP value.\n", loglvl);
112119 } else {
113120 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
5858 * or a page fault), which can make frame pointers
5959 * unreliable.
6060 */
61−
6261 if (IS_ENABLED(CONFIG_FRAME_POINTER))
6362 return -EINVAL;
6463 }
@@ -81,10 +80,6 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, · 16 unmodified lines
8180 if (unwind_error(&state))
8281 return -EINVAL;
8382
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−
8883 return 0;
8984 }
9085
arch/x86/kernel/unwind_orc.c+6−2
@@ -440,8 +440,11 @@ bool unwind_next_frame(struct unwind_state *state) · 439 unmodified lines
440440 /*
441441 * Find the orc_entry associated with the text address.
442442 *
443− * Decrement call return addresses by one so they work for sibling
444− * calls and calls to noreturn functions.
443+ * For a call frame (as opposed to a signal frame), state->ip points to
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.
445448 */
446449 orc = orc_find(state->signal ? state->ip : state->ip - 1);
447450 if (!orc) {
@@ -662,6 +665,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, · 214 unmodified lines
662665 state->sp = task->thread.sp;
663666 state->bp = READ_ONCE_NOCHECK(frame->bp);
664667 state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
668+ state->signal = (void *)state->ip == ret_from_fork;
665669 }
666670
667671 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
358358 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
359359 __bss_start = .;
360360 *(.bss..page_aligned)
361+ . = ALIGN(PAGE_SIZE);
361362 *(BSS_MAIN)
362363 BSS_DECRYPTED
363364 . = ALIGN(PAGE_SIZE);
include/asm-generic/vmlinux.lds.h+4−1
@@ -341,7 +341,8 @@ · 340 unmodified lines
341341
342342 #define PAGE_ALIGNED_DATA(page_align) \
343343 . = ALIGN(page_align); \
344− *(.data..page_aligned)
344+ *(.data..page_aligned) \
345+ . = ALIGN(page_align);
345346
346347 #define READ_MOSTLY_DATA(align) \
347348 . = ALIGN(align); \
@@ -737,7 +738,9 @@ · 389 unmodified lines
737738 . = ALIGN(bss_align); \
738739 .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \
739740 BSS_FIRST_SECTIONS \
741+ . = ALIGN(PAGE_SIZE); \
740742 *(.bss..page_aligned) \
743+ . = ALIGN(PAGE_SIZE); \
741744 *(.dynbss) \
742745 *(BSS_MAIN) \
743746 *(COMMON) \