Skip to content

Commit

Permalink
x86/entry/32: Add debug code to check entry/exit CR3
Browse files Browse the repository at this point in the history
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: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Pavel 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
  • Loading branch information
joergroedel authored and KAGA-KOKO committed Jul 19, 2018
1 parent 5e81059 commit 9719370
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions arch/x86/entry/entry_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
*
Expand All @@ -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
Expand Down Expand Up @@ -287,6 +308,8 @@

.Lswitched_\@:

BUG_IF_WRONG_CR3

RESTORE_REGS pop=\pop
.endm

Expand Down Expand Up @@ -357,6 +380,8 @@

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

BUG_IF_WRONG_CR3

SWITCH_TO_KERNEL_CR3 scratch_reg=%eax

/*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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:
Expand All @@ -983,13 +1012,27 @@ restore_all:
restore_all_kernel:
TRACE_IRQS_IRET
PARANOID_EXIT_TO_KERNEL_MODE
BUG_IF_WRONG_CR3
RESTORE_REGS 4
jmp .Lirq_return

.section .fixup, "ax"
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)
Expand Down

0 comments on commit 9719370

Please sign in to comment.