linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mark Rutland <mark.rutland@arm.com>
To: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org
Cc: dan.j.williams@intel.com, elena.reshetova@intel.com,
	corbet@lwn.net, alan@linux.intel.com, peterz@infradead.org,
	will.deacon@arm.com, gregkh@linuxfoundation.org,
	tglx@linutronix.de, Mark Rutland <mark.rutland@arm.com>
Subject: [RFCv2 1/4] asm-generic/barrier: add generic nospec helpers
Date: Fri,  5 Jan 2018 14:57:47 +0000	[thread overview]
Message-ID: <20180105145750.53294-2-mark.rutland@arm.com> (raw)
In-Reply-To: <20180105145750.53294-1-mark.rutland@arm.com>

Under speculation, CPUs may mis-predict branches in bounds checks. Thus,
memory accesses under a bounds check may be speculated even if the
bounds check fails, providing a primitive for building a side channel.

This patch adds helpers which can be used to inhibit the use of
out-of-bounds pointers under speculation.

A generic implementation is provided for compatibility, but does not
guarantee safety under speculation. Architectures are expected to
override these helpers as necessary.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Cc: Daniel Willams <dan.j.williams@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
 include/asm-generic/barrier.h | 68 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

Dan, I've reworked this so that nospec_ptr() can take an arch-specific barrier
sequence. I believe that for x86 you just need to implement __nospec_barrier()
as osb().

Mark.

diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h
index fe297b599b0a..91c3071f49e5 100644
--- a/include/asm-generic/barrier.h
+++ b/include/asm-generic/barrier.h
@@ -54,6 +54,74 @@
 #define read_barrier_depends()		do { } while (0)
 #endif
 
+/*
+ * Inhibit subsequent speculative memory accesses.
+ *
+ * Architectures with a suitable memory barrier should provide an
+ * implementation. This is non-portable, and generic code should use
+ * nospec_ptr().
+ */
+#ifndef __nospec_barrier
+#define __nospec_barrier()		do { } while (0)
+#endif
+
+/**
+ * nospec_ptr() - Ensure a  pointer is bounded, even under speculation.
+ *
+ * @ptr: the pointer to test
+ * @lo: the lower valid bound for @ptr, inclusive
+ * @hi: the upper valid bound for @ptr, exclusive
+ *
+ * If @ptr falls in the interval [@lo, @i), returns @ptr, otherwise returns
+ * NULL.
+ *
+ * Architectures which do not provide __nospec_barrier() should override this
+ * to ensure that ptr falls in the [lo, hi) interval both under architectural
+ * execution and under speculation, preventing propagation of an out-of-bounds
+ * pointer to code which is speculatively executed.
+ */
+#ifndef nospec_ptr
+#define nospec_ptr(ptr, lo, hi)						\
+({									\
+	typeof (ptr) __ret;						\
+	typeof (ptr) __ptr = (ptr);					\
+	typeof (ptr) __lo = (lo);					\
+	typeof (ptr) __hi = (hi);					\
+									\
+	__ret = (__lo <= __ptr && __ptr < __hi) ? __ptr : NULL;		\
+									\
+	__nospec_barrier();						\
+									\
+	__ret;								\
+})
+#endif
+
+/**
+ * nospec_array_ptr - Generate a pointer to an array element, ensuring the
+ * pointer is bounded under speculation.
+ *
+ * @arr: the base of the array
+ * @idx: the index of the element
+ * @sz: the number of elements in the array
+ *
+ * If @idx falls in the interval [0, @sz), returns the pointer to @arr[@idx],
+ * otherwise returns NULL.
+ *
+ * This is a wrapper around nospec_ptr(), provided for convenience.
+ * Architectures should implement nospec_ptr() to ensure this is the case
+ * under speculation.
+ */
+#define nospec_array_ptr(arr, idx, sz)					\
+({									\
+	typeof(*(arr)) *__arr = (arr);					\
+	typeof(idx) __idx = (idx);					\
+	typeof(sz) __sz = (sz);						\
+									\
+	nospec_ptr(__arr + __idx, __arr, __arr + __sz);			\
+})
+
+#undef __nospec_barrier
+
 #ifndef __smp_mb
 #define __smp_mb()	mb()
 #endif
-- 
2.11.0

  parent reply	other threads:[~2018-01-05 14:57 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-05 14:57 [RFCv2 0/4] API for inhibiting speculative arbitrary read primitives Mark Rutland
2018-01-05 14:57 ` Mark Rutland
2018-01-05 14:57 ` Mark Rutland [this message]
2018-01-05 14:57   ` [RFCv2 1/4] asm-generic/barrier: add generic nospec helpers Mark Rutland
2018-01-08 21:47   ` Mark Salter
2018-01-05 14:57 ` [RFCv2 2/4] Documentation: document " Mark Rutland
2018-01-05 14:57   ` Mark Rutland
2018-01-07  5:20   ` Randy Dunlap
2018-01-07 13:06     ` Mark Rutland
2018-01-07 10:27   ` Geert Uytterhoeven
2018-01-07 10:27     ` Geert Uytterhoeven
2018-01-05 14:57 ` [RFCv2 3/4] arm64: implement nospec_ptr() Mark Rutland
2018-01-05 14:57 ` [RFCv2 4/4] bpf: inhibit speculated out-of-bounds pointers Mark Rutland
2018-01-05 14:57   ` Mark Rutland
2018-01-05 16:38   ` Dan Williams
2018-01-05 16:48     ` Mark Rutland
2018-01-05 17:04   ` Alexei Starovoitov
2018-01-08 12:59     ` Reshetova, Elena
2018-01-08 12:59       ` Reshetova, Elena

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=20180105145750.53294-2-mark.rutland@arm.com \
    --to=mark.rutland@arm.com \
    --cc=alan@linux.intel.com \
    --cc=corbet@lwn.net \
    --cc=dan.j.williams@intel.com \
    --cc=elena.reshetova@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=will.deacon@arm.com \
    /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).