linux/arch/x86/entry
Ingo Molnar 6c0398cfeb x86/entry/64: Fix CR3 restore in paranoid_exit()
commit e486575734 upstream.

Josh Poimboeuf noticed the following bug:

 "The paranoid exit code only restores the saved CR3 when it switches back
  to the user GS.  However, even in the kernel GS case, it's possible that
  it needs to restore a user CR3, if for example, the paranoid exception
  occurred in the syscall exit path between SWITCH_TO_USER_CR3_STACK and
  SWAPGS."

Josh also confirmed via targeted testing that it's possible to hit this bug.

Fix the bug by also restoring CR3 in the paranoid_exit_no_swapgs branch.

The reason we haven't seen this bug reported by users yet is probably because
"paranoid" entry points are limited to the following cases:

 idtentry double_fault       do_double_fault  has_error_code=1  paranoid=2
 idtentry debug              do_debug         has_error_code=0  paranoid=1 shift_ist=DEBUG_STACK
 idtentry int3               do_int3          has_error_code=0  paranoid=1 shift_ist=DEBUG_STACK
 idtentry machine_check      do_mce           has_error_code=0  paranoid=1

Amongst those entry points only machine_check is one that will interrupt an
IRQS-off critical section asynchronously - and machine check events are rare.

The other main asynchronous entries are NMI entries, which can be very high-freq
with perf profiling, but they are special: they don't use the 'idtentry' macro but
are open coded and restore user CR3 unconditionally so don't have this bug.

Reported-and-tested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Reviewed-by: Andy Lutomirski <luto@kernel.org>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180214073910.boevmg65upbk3vqb@gmail.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2018-02-22 15:42:24 +01:00
..
syscalls x86/build: Beautify build log of syscall headers 2017-12-25 14:26:16 +01:00
vdso License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
vsyscall x86/pti: Map the vsyscall page if needed 2018-01-02 20:31:00 +01:00
calling.h x86/entry/64: Remove the unused 'icebp' macro 2018-02-22 15:42:22 +01:00
common.c x86/syscall: Sanitize syscall table de-references under speculation 2018-02-07 11:12:23 -08:00
entry_32.S x86/retpoline: Simplify vmexit_fill_RSB() 2018-02-07 11:12:20 -08:00
entry_64.S x86/entry/64: Fix CR3 restore in paranoid_exit() 2018-02-22 15:42:24 +01:00
entry_64_compat.S x86/entry/64/compat: Clear registers for compat syscalls, to reduce speculation attack surface 2018-02-22 15:42:19 +01:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
syscall_32.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
syscall_64.c x86/entry/64: Remove the SYSCALL64 fast path 2018-02-07 11:12:22 -08:00
thunk_32.S x86: move exports to actual definitions 2016-08-07 23:47:15 -04:00
thunk_64.S x86: move exports to actual definitions 2016-08-07 23:47:15 -04:00