Skip to contentSkip to conversation

Patch "[Variant 1/Spectre-v1] arm64: Use pointer masking to limit uaccess speculation" has been added to the 4.14-stable tree

PATCH [email protected] 1 participant 1 message Feb 14, 2018

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

[Variant 1/Spectre-v1] arm64: Use pointer masking to limit uaccess speculation

to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
arm64-use-pointer-masking-to-limit-uaccess-speculation.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Wed Feb 14 14:44:54 CET 2018

From: Robin Murphy <[email protected]>
Date: Mon, 5 Feb 2018 15:34:19 +0000
Subject: [Variant 1/Spectre-v1] arm64: Use pointer masking to limit uaccess speculation

From: Robin Murphy <[email protected]>

Commit 4d8efc2d5ee4 upstream.

Similarly to x86, mitigate speculation past an access_ok() check by masking the pointer against the address limit before use.

Even if we don't expect speculative writes per se, it is plausible that a CPU may still speculate at least as far as fetching a cache line for writing, hence we also harden put_user() and clear_user() for peace of mind.

---
 arch/arm64/include/asm/uaccess.h |   26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)
arch/arm64/include/asm/uaccess.h +23 -3
@@ -216,6 +216,26 @@ static inline void uaccess_enable_not_ua
 }
 
 /*
+ * Sanitise a uaccess pointer such that it becomes NULL if above the
+ * current addr_limit.
+ */
+#define uaccess_mask_ptr(ptr) (__typeof__(ptr))__uaccess_mask_ptr(ptr)
+static inline void __user *__uaccess_mask_ptr(const void __user *ptr)
+{
+	void __user *safe_ptr;
+
+	asm volatile(
+	"	bics	xzr, %1, %2\n"
+	"	csel	%0, %1, xzr, eq\n"
+	: "=&r" (safe_ptr)
+	: "r" (ptr), "r" (current_thread_info()->addr_limit)
+	: "cc");
+
+	csdb();
+	return safe_ptr;
+}
+
+/*
  * The "__xxx" versions of the user access functions do not verify the address
  * space - it must have been done previously with a separate "access_ok()"
  * call.
@@ -285,7 +305,7 @@ do {									\
 	__typeof__(*(ptr)) __user *__p = (ptr);				\
 	might_fault();							\
 	access_ok(VERIFY_READ, __p, sizeof(*__p)) ?			\
-		__get_user((x), __p) :					\
+		__p = uaccess_mask_ptr(__p), __get_user((x), __p) :	\
 		((x) = 0, -EFAULT);					\
 })
 
@@ -349,7 +369,7 @@ do {									\
 	__typeof__(*(ptr)) __user *__p = (ptr);				\
 	might_fault();							\
 	access_ok(VERIFY_WRITE, __p, sizeof(*__p)) ?			\
-		__put_user((x), __p) :					\
+		__p = uaccess_mask_ptr(__p), __put_user((x), __p) :	\
 		-EFAULT;						\
 })
 
@@ -365,7 +385,7 @@ extern unsigned long __must_check __clea
 static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
 {
 	if (access_ok(VERIFY_WRITE, to, n))
-		n = __clear_user(to, n);
+		n = __clear_user(__uaccess_mask_ptr(to), n);
 	return n;
 }
 

Patches currently in stable-queue which might be from [email protected] are

queue-4.14/arm64-make-user_ds-an-inclusive-limit.patch queue-4.14/arm64-uaccess-don-t-bother-eliding-access_ok-checks-in-__-get-put-_user.patch queue-4.14/arm-arm64-smccc-make-function-identifiers-an-unsigned-quantity.patch queue-4.14/firmware-psci-expose-psci-conduit.patch queue-4.14/firmware-psci-expose-smccc-version-through-psci_ops.patch queue-4.14/arm64-use-pointer-masking-to-limit-uaccess-speculation.patch queue-4.14/arm-arm64-smccc-implement-smccc-v1.1-inline-primitive.patch queue-4.14/arm64-implement-array_index_mask_nospec.patch