From 22b8e64b951234f9e5a6250e2389564bd4101915 Mon Sep 17 00:00:00 2001 From: George Dunlap Date: Mon, 23 Dec 2019 18:00:55 +0000 Subject: [PATCH 3/4] nospec: Introduce nospec_clip macro There are lots of places in the code where we might want to: 1. Do a bounds check and return an error 2. Use the array_index_nospec() macro to prevent Spectre-style attacks during speculation. Create a simple macro to clip an index and return true if it was clipped. This allows us to "fully" sanitize an index passed from userspace in a single check, thus: if ( nospec_clip(index, INDEX_MAX) ) return -EINVAL; Afterwards, `index` wil be safe against speculation, having been clipped via array_index_nospec(). Signed-off-by: George Dunlap --- xen/include/xen/nospec.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/xen/include/xen/nospec.h b/xen/include/xen/nospec.h index 76255bc46e..1cc0301848 100644 --- a/xen/include/xen/nospec.h +++ b/xen/include/xen/nospec.h @@ -64,6 +64,21 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, #define array_index_nospec(index, size) ((void)(size), (index)) #endif /* CONFIG_SPECULATIVE_HARDEN_ARRAY */ +/* + * nospec_clip - Do a bounds check and make an index speculation safe + * + * Use to simultaneously check the size and clip it appropriately, thus: + * + * if ( nospec_clip(index, size) ) + * return -EINVAL; + */ +#define nospec_clip(index, size) \ + ({ \ + bool clipped = (index >= size); \ + index = array_index_nospec(index, size); \ + clipped; \ + }) + /* * array_access_nospec - allow nospec access for static size arrays */ -- 2.24.0