1
0
Fork 0
alistair23-linux/arch/x86/entry
Josh Poimboeuf db00b1d9d7 x86/unwind/orc: Fix premature unwind stoppage due to IRET frames
commit 81b67439d1 upstream.

The following execution path is possible:

  fsnotify()
    [ realign the stack and store previous SP in R10 ]
    <IRQ>
      [ only IRET regs saved ]
      common_interrupt()
        interrupt_entry()
	  <NMI>
	    [ full pt_regs saved ]
	    ...
	    [ unwind stack ]

When the unwinder goes through the NMI and the IRQ on the stack, and
then sees fsnotify(), it doesn't have access to the value of R10,
because it only has the five IRET registers.  So the unwind stops
prematurely.

However, because the interrupt_entry() code is careful not to clobber
R10 before saving the full regs, the unwinder should be able to read R10
from the previously saved full pt_regs associated with the NMI.

Handle this case properly.  When encountering an IRET regs frame
immediately after a full pt_regs frame, use the pt_regs as a backup
which can be used to get the C register values.

Also, note that a call frame resets the 'prev_regs' value, because a
function is free to clobber the registers.  For this fix to work, the
IRET and full regs frames must be adjacent, with no FUNC frames in
between.  So replace the FUNC hint in interrupt_entry() with an
IRET_REGS hint.

Fixes: ee9f8fce99 ("x86/unwind: Add the ORC unwinder")
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Dave Jones <dsj@fb.com>
Cc: Jann Horn <jannh@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: https://lore.kernel.org/r/97a408167cc09f1cfa0de31a7b70dd88868d743f.1587808742.git.jpoimboe@redhat.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-14 07:58:29 +02:00
..
syscalls syscalls/x86: Use the correct function type for sys_ni_syscall 2020-01-17 19:48:31 +01:00
vdso x86/vdso: Provide missing include file 2020-02-24 08:36:41 +01:00
vsyscall Merge branch 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2019-07-08 21:48:15 -07:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
calling.h x86/entry/64: Fix unwind hints in register clearing code 2020-05-14 07:58:28 +02:00
common.c x86/syscalls: Split the x32 syscalls into their own table 2019-07-22 10:31:23 +02:00
entry_32.S x86/entry/32: Add missing ASM_CLAC to general_protection entry 2020-04-17 10:50:13 +02:00
entry_64.S x86/unwind/orc: Fix premature unwind stoppage due to IRET frames 2020-05-14 07:58:29 +02:00
entry_64_compat.S x86/entry/64/compat: Fix stack switching for XEN PV 2019-01-18 00:39:33 +01:00
syscall_32.c syscalls/x86: Use the correct function type for sys_ni_syscall 2020-01-17 19:48:31 +01:00
syscall_64.c syscalls/x86: Use the correct function type for sys_ni_syscall 2020-01-17 19:48:31 +01:00
thunk_32.S x86: Use CONFIG_PREEMPTION 2019-07-31 19:03:35 +02:00
thunk_64.S x86: Use CONFIG_PREEMPTION 2019-07-31 19:03:35 +02:00