Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97193702 authored by Joerg Roedel's avatar Joerg Roedel Committed by Thomas Gleixner
Browse files

x86/entry/32: Add debug code to check entry/exit CR3



Add code to check whether the kernel is entered and left with the correct
CR3 and make it depend on CONFIG_DEBUG_ENTRY.  This is needed because there
is no NX protection of user-addresses in the kernel-CR3 on x86-32 and that
type of bug would not be detected otherwise.

Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarPavel Machek <pavel@ucw.cz>
Cc: "H . Peter Anvin" <hpa@zytor.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Laight <David.Laight@aculab.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Eduardo Valentin <eduval@amazon.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: aliguori@amazon.com
Cc: daniel.gruss@iaik.tugraz.at
Cc: hughd@google.com
Cc: keescook@google.com
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Waiman Long <llong@redhat.com>
Cc: "David H . Gutteridge" <dhgutteridge@sympatico.ca>
Cc: joro@8bytes.org
Link: https://lkml.kernel.org/r/1531906876-13451-40-git-send-email-joro@8bytes.org
parent 5e810595
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -166,6 +166,24 @@
.Lend_\@:
.endm

.macro BUG_IF_WRONG_CR3 no_user_check=0
#ifdef CONFIG_DEBUG_ENTRY
	ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
	.if \no_user_check == 0
	/* coming from usermode? */
	testl	$SEGMENT_RPL_MASK, PT_CS(%esp)
	jz	.Lend_\@
	.endif
	/* On user-cr3? */
	movl	%cr3, %eax
	testl	$PTI_SWITCH_MASK, %eax
	jnz	.Lend_\@
	/* From userspace with kernel cr3 - BUG */
	ud2
.Lend_\@:
#endif
.endm

/*
 * Switch to kernel cr3 if not already loaded and return current cr3 in
 * \scratch_reg
@@ -213,6 +231,8 @@
.macro SAVE_ALL_NMI cr3_reg:req
	SAVE_ALL

	BUG_IF_WRONG_CR3

	/*
	 * Now switch the CR3 when PTI is enabled.
	 *
@@ -224,6 +244,7 @@

.Lend_\@:
.endm

/*
 * This is a sneaky trick to help the unwinder find pt_regs on the stack.  The
 * frame pointer is replaced with an encoded pointer to pt_regs.  The encoding
@@ -287,6 +308,8 @@

.Lswitched_\@:

	BUG_IF_WRONG_CR3

	RESTORE_REGS pop=\pop
.endm

@@ -357,6 +380,8 @@

	ALTERNATIVE     "", "jmp .Lend_\@", X86_FEATURE_XENPV

	BUG_IF_WRONG_CR3

	SWITCH_TO_KERNEL_CR3 scratch_reg=%eax

	/*
@@ -799,6 +824,7 @@ ENTRY(entry_SYSENTER_32)
	 */
	pushfl
	pushl	%eax
	BUG_IF_WRONG_CR3 no_user_check=1
	SWITCH_TO_KERNEL_CR3 scratch_reg=%eax
	popl	%eax
	popfl
@@ -893,6 +919,7 @@ ENTRY(entry_SYSENTER_32)
	 * whereas POPF does not.)
	 */
	btrl	$X86_EFLAGS_IF_BIT, (%esp)
	BUG_IF_WRONG_CR3 no_user_check=1
	popfl
	popl	%eax

@@ -970,6 +997,8 @@ restore_all:
	/* Switch back to user CR3 */
	SWITCH_TO_USER_CR3 scratch_reg=%eax

	BUG_IF_WRONG_CR3

	/* Restore user state */
	RESTORE_REGS pop=4			# skip orig_eax/error_code
.Lirq_return:
@@ -983,6 +1012,7 @@ restore_all:
restore_all_kernel:
	TRACE_IRQS_IRET
	PARANOID_EXIT_TO_KERNEL_MODE
	BUG_IF_WRONG_CR3
	RESTORE_REGS 4
	jmp	.Lirq_return

@@ -990,6 +1020,19 @@ restore_all_kernel:
ENTRY(iret_exc	)
	pushl	$0				# no error code
	pushl	$do_iret_error

#ifdef CONFIG_DEBUG_ENTRY
	/*
	 * The stack-frame here is the one that iret faulted on, so its a
	 * return-to-user frame. We are on kernel-cr3 because we come here from
	 * the fixup code. This confuses the CR3 checker, so switch to user-cr3
	 * as the checker expects it.
	 */
	pushl	%eax
	SWITCH_TO_USER_CR3 scratch_reg=%eax
	popl	%eax
#endif

	jmp	common_exception
.previous
	_ASM_EXTABLE(.Lirq_return, iret_exc)