Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1508170

[tip:x86/urgent] x86/unwind: Fix empty stack dereference in guess unwinder

From tip-bot for Josh Poimboeuf <tipbot@zytor.com>
Newsgroups linux.kernel
Subject [tip:x86/urgent] x86/unwind: Fix empty stack dereference in guess unwinder
Date 2016-10-25 12:40 +0200
Message-ID <sw7jc-4nV-15@gated-at.bofh.it> (permalink)
References <svNDV-8aC-17@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


Commit-ID:  7fbe6ac02485504b964b283aca62b36b4313ca79
Gitweb:     http://git.kernel.org/tip/7fbe6ac02485504b964b283aca62b36b4313ca79
Author:     Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate: Mon, 24 Oct 2016 08:31:27 -0500
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 25 Oct 2016 11:36:43 +0200

x86/unwind: Fix empty stack dereference in guess unwinder

Vince Waver reported the following bug:

  WARNING: CPU: 0 PID: 21338 at arch/x86/mm/fault.c:435 vmalloc_fault+0x58/0x1f0
  CPU: 0 PID: 21338 Comm: perf_fuzzer Not tainted 4.8.0+ #37
  Hardware name: Hewlett-Packard HP Compaq Pro 6305 SFF/1850, BIOS K06 v02.57 08/16/2013
  Call Trace:
   <NMI>  ? dump_stack+0x46/0x59
   ? __warn+0xd5/0xee
   ? vmalloc_fault+0x58/0x1f0
   ? __do_page_fault+0x6d/0x48e
   ? perf_log_throttle+0xa4/0xf4
   ? trace_page_fault+0x22/0x30
   ? __unwind_start+0x28/0x42
   ? perf_callchain_kernel+0x75/0xac
   ? get_perf_callchain+0x13a/0x1f0
   ? perf_callchain+0x6a/0x6c
   ? perf_prepare_sample+0x71/0x2eb
   ? perf_event_output_forward+0x1a/0x54
   ? __default_send_IPI_shortcut+0x10/0x2d
   ? __perf_event_overflow+0xfb/0x167
   ? x86_pmu_handle_irq+0x113/0x150
   ? native_read_msr+0x6/0x34
   ? perf_event_nmi_handler+0x22/0x39
   ? perf_ibs_nmi_handler+0x4a/0x51
   ? perf_event_nmi_handler+0x22/0x39
   ? nmi_handle+0x4d/0xf0
   ? perf_ibs_handle_irq+0x3d1/0x3d1
   ? default_do_nmi+0x3c/0xd5
   ? do_nmi+0x92/0x102
   ? end_repeat_nmi+0x1a/0x1e
   ? entry_SYSCALL_64_after_swapgs+0x12/0x4a
   ? entry_SYSCALL_64_after_swapgs+0x12/0x4a
   ? entry_SYSCALL_64_after_swapgs+0x12/0x4a
   <EOE> ^A4---[ end trace 632723104d47d31a ]---
  BUG: stack guard page was hit at ffffc90008500000 (stack is ffffc900084fc000..ffffc900084fffff)
  kernel stack overflow (page fault): 0000 [#1] SMP
  ...

The NMI hit in the entry code right after setting up the stack pointer
from 'cpu_current_top_of_stack', so the kernel stack was empty.  The
'guess' version of __unwind_start() attempted to dereference the "top of
stack" pointer, which is not actually *on* the stack.

Add a check in the guess unwinder to deal with an empty stack.  (The
frame pointer unwinder already has such a check.)

Reported-by: Vince Weaver <vincent.weaver@maine.edu>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Fixes: 7c7900f89770 ("x86/unwind: Add new unwind interface and implementations")
Link: http://lkml.kernel.org/r/20161024133127.e5evgeebdbohnmpb@treble
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/unwind_guess.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/unwind_guess.c b/arch/x86/kernel/unwind_guess.c
index 9298993..2d721e5 100644
--- a/arch/x86/kernel/unwind_guess.c
+++ b/arch/x86/kernel/unwind_guess.c
@@ -47,7 +47,14 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
 	get_stack_info(first_frame, state->task, &state->stack_info,
 		       &state->stack_mask);
 
-	if (!__kernel_text_address(*first_frame))
+	/*
+	 * The caller can provide the address of the first frame directly
+	 * (first_frame) or indirectly (regs->sp) to indicate which stack frame
+	 * to start unwinding at.  Skip ahead until we reach it.
+	 */
+	if (!unwind_done(state) &&
+	    (!on_stack(&state->stack_info, first_frame, sizeof(long)) ||
+	    !__kernel_text_address(*first_frame)))
 		unwind_next_frame(state);
 }
 EXPORT_SYMBOL_GPL(__unwind_start);

Back to linux.kernel | Previous | Next — Previous in thread | Find similar | Unroll thread


Thread

perf: perf_fuzzer triggers vmalloc_fault (then crashes) Vince Weaver <vincent.weaver@maine.edu> - 2016-10-22 05:10 +0200
  Re: perf: perf_fuzzer triggers vmalloc_fault (then crashes) Peter Zijlstra <peterz@infradead.org> - 2016-10-24 12:20 +0200
    Re: perf: perf_fuzzer triggers vmalloc_fault (then crashes) Josh Poimboeuf <jpoimboe@redhat.com> - 2016-10-24 13:20 +0200
      Re: perf: perf_fuzzer triggers vmalloc_fault (then crashes) Peter Zijlstra <peterz@infradead.org> - 2016-10-24 13:20 +0200
        [PATCH] x86/unwind: fix empty stack dereference in guess unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2016-10-24 15:40 +0200
          [tip:x86/urgent] x86/unwind: Fix empty stack dereference in guess  unwinder tip-bot for Josh Poimboeuf <tipbot@zytor.com> - 2016-10-25 12:40 +0200

csiph-web