linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: tip-bot for Kees Cook <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: solar@openwall.com, keescook@chromium.org,
	gregkh@linuxfoundation.org, linux@dominikbrodowski.net,
	tglx@linutronix.de, sean.j.christopherson@intel.com,
	hpa@zytor.com, mingo@kernel.org, peterz@infradead.org,
	linux-kernel@vger.kernel.org,
	kernel-hardening@lists.openwall.com, jannh@google.com
Subject: [tip:x86/asm] x86/asm: Pin sensitive CR0 bits
Date: Wed, 6 Mar 2019 05:31:56 -0800	[thread overview]
Message-ID: <tip-d884bc119c4ebe7ac53b61fc0750bbc89b4d63db@git.kernel.org> (raw)
In-Reply-To: <20190227200132.24707-2-keescook@chromium.org>

Commit-ID:  d884bc119c4ebe7ac53b61fc0750bbc89b4d63db
Gitweb:     https://git.kernel.org/tip/d884bc119c4ebe7ac53b61fc0750bbc89b4d63db
Author:     Kees Cook <keescook@chromium.org>
AuthorDate: Wed, 27 Feb 2019 12:01:30 -0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 6 Mar 2019 13:25:55 +0100

x86/asm: Pin sensitive CR0 bits

With sensitive CR4 bits pinned now, it's possible that the WP bit for CR0
might become a target as well. Following the same reasoning for the CR4
pinning, pin CR0's WP bit (but this can be done with a static value).

As before, to convince the compiler to not optimize away the check for the
WP bit after the set, mark "val" as an output from the asm() block.  This
protects against just jumping into the function past where the masking
happens; we must check that the mask was applied after we do the set). Due
to how this function can be built by the compiler (especially due to the
removal of frame pointers), jumping into the middle of the function
frequently doesn't require stack manipulation to construct a stack frame
(there may only a retq without pops, which is sufficient for use with
exploits like timer overwrites).

Additionally, this avoids WARN()ing before resetting the bit, just to
minimize any race conditions with leaving the bit unset.

Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Solar Designer <solar@openwall.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Jann Horn <jannh@google.com>
Cc: Sean Christopherson <sean.j.christopherson@intel.com>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Kernel Hardening <kernel-hardening@lists.openwall.com>
Link: https://lkml.kernel.org/r/20190227200132.24707-2-keescook@chromium.org

---
 arch/x86/include/asm/special_insns.h | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h
index 99607f142cad..7fa4fe880395 100644
--- a/arch/x86/include/asm/special_insns.h
+++ b/arch/x86/include/asm/special_insns.h
@@ -5,6 +5,7 @@
 
 #ifdef __KERNEL__
 
+#include <asm/processor-flags.h>
 #include <asm/nops.h>
 
 /*
@@ -25,7 +26,28 @@ static inline unsigned long native_read_cr0(void)
 
 static inline void native_write_cr0(unsigned long val)
 {
-	asm volatile("mov %0,%%cr0": : "r" (val), "m" (__force_order));
+	bool warn = false;
+
+again:
+	val |= X86_CR0_WP;
+	/*
+	 * In order to have the compiler not optimize away the check
+	 * after the cr4 write, mark "val" as being also an output ("+r")
+	 * by this asm() block so it will perform an explicit check, as
+	 * if it were "volatile".
+	 */
+	asm volatile("mov %0,%%cr0" : "+r" (val) : "m" (__force_order) : );
+	/*
+	 * If the MOV above was used directly as a ROP gadget we can
+	 * notice the lack of pinned bits in "val" and start the function
+	 * from the beginning to gain the WP bit for sure. And do it
+	 * without first taking the exception for a WARN().
+	 */
+	if ((val & X86_CR0_WP) != X86_CR0_WP) {
+		warn = true;
+		goto again;
+	}
+	WARN_ONCE(warn, "Attempt to unpin X86_CR0_WP, cr0 bypass attack?!\n");
 }
 
 static inline unsigned long native_read_cr2(void)

  parent reply	other threads:[~2019-03-06 13:32 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-27 20:01 [PATCH v2 0/3] x86/asm: More pinning Kees Cook
2019-02-27 20:01 ` [PATCH v2 1/3] x86/asm: Pin sensitive CR0 bits Kees Cook
2019-03-06  9:55   ` [tip:x86/asm] " tip-bot for Kees Cook
2019-03-06 13:31   ` tip-bot for Kees Cook [this message]
2019-02-27 20:01 ` [PATCH v2 2/3] x86/asm: Avoid taking an exception before cr4 restore Kees Cook
2019-03-06  9:55   ` [tip:x86/asm] " tip-bot for Kees Cook
2019-03-06 13:31   ` tip-bot for Kees Cook
2019-02-27 20:01 ` [PATCH v2 3/3] lkdtm: Check for SMEP clearing protections Kees Cook
2019-03-06  9:56   ` [tip:x86/asm] " tip-bot for Kees Cook
2019-03-06 13:32   ` tip-bot for Kees Cook
2019-06-18  4:55 [PATCH v3 3/3] x86/asm: Pin sensitive CR0 bits Kees Cook
2019-06-22  9:58 ` [tip:x86/asm] " tip-bot for Kees Cook

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tip-d884bc119c4ebe7ac53b61fc0750bbc89b4d63db@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hpa@zytor.com \
    --cc=jannh@google.com \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=linux@dominikbrodowski.net \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=sean.j.christopherson@intel.com \
    --cc=solar@openwall.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).