Changes since v2 [1]: * style fix in Documentation/speculation.txt (Geert) * add Russell and Catalin to the cc on the ARM patches (Russell) * clarify changelog for "x86: introduce __uaccess_begin_nospec and ASM_IFENCE" (Eric, Linus, Josh) * fix the dynamic 'mask' / 'ifence' toggle vs CONFIG_JUMP_LABEL=n (Peter) * include the get_user_{1,2,4,8} helpers in the ASM_IFENCE protections (Linus) * fix array_ptr_mask for ARCH=i386 builds (Kbuild robot) * prioritize the get_user protections, and the fdtable fix [1]: https://lwn.net/Articles/744141/ --- Quoting Mark's original RFC: "Recently, Google Project Zero discovered several classes of attack against speculative execution. One of these, known as variant-1, allows explicit bounds checks to be bypassed under speculation, providing an arbitrary read gadget. Further details can be found on the GPZ blog [2] and the Documentation patch in this series." This series incorporates Mark Rutland's latest ARM changes and adds the x86 specific implementation of 'ifence_array_ptr'. That ifence based approach is provided as an opt-in fallback, but the default mitigation, '__array_ptr', uses a 'mask' approach that removes conditional branches instructions, and otherwise aims to redirect speculation to use a NULL pointer rather than a user controlled value. The mask is generated by the following from Alexei, and Linus: mask = ~(long)(_i | (_s - 1 - _i)) >> (BITS_PER_LONG - 1); ...and Linus provided an optimized mask generation helper for x86: asm ("cmpq %1,%2; sbbq %0,%0;" :"=r" (mask) :"r"(sz),"r" (idx) :"cc"); The 'array_ptr' mechanism can be switched between 'mask' and 'ifence' via the spectre_v1={mask,ifence} command line option if CONFIG_SPECTRE1_DYNAMIC=y, and the compile-time default is otherwise set by selecting either CONFIG_SPECTRE1_MASK or CONFIG_SPECTRE1_IFENCE. This level of sophistication is provided given concerns about 'value speculation' [3]. The get_user protections and 'array_ptr' infrastructure are the only concern of this patch set. Going forward 'array_ptr' is a tool that sub-system maintainers can use to instrument array bounds checks like '__fcheck_files'. When to use 'array_ptr' is saved for a future patch set, and in the meantime the 'get_user' protections raise the bar for launching a Spectre-v1 attack. These patches are also available via the 'nospec-v3' git branch here: git://git.kernel.org/pub/scm/linux/kernel/git/djbw/linux nospec-v3 Note that the BPF fix for Spectre variant1 is merged for 4.15-rc8. [2]: https://googleprojectzero.blogspot.co.uk/2018/01/reading-privileged-memory-with-side.html [3]: https://marc.info/?l=linux-netdev&m=151527996901350&w=2 --- Dan Williams (6): x86: implement ifence() x86: implement ifence_array_ptr() and array_ptr_mask() asm/nospec: mask speculative execution flows x86: introduce __uaccess_begin_nospec and ASM_IFENCE x86: use __uaccess_begin_nospec and ASM_IFENCE in get_user paths vfs, fdtable: prevent bounds-check bypass via speculative execution Mark Rutland (3): Documentation: document array_ptr arm64: implement ifence_array_ptr() arm: implement ifence_array_ptr() Documentation/speculation.txt | 143 +++++++++++++++++++++++++++++++++++++ arch/arm/Kconfig | 1 arch/arm/include/asm/barrier.h | 24 ++++++ arch/arm64/Kconfig | 1 arch/arm64/include/asm/barrier.h | 24 ++++++ arch/x86/Kconfig | 3 + arch/x86/include/asm/barrier.h | 50 +++++++++++++ arch/x86/include/asm/msr.h | 3 - arch/x86/include/asm/smap.h | 4 + arch/x86/include/asm/uaccess.h | 16 +++- arch/x86/include/asm/uaccess_32.h | 6 +- arch/x86/include/asm/uaccess_64.h | 12 ++- arch/x86/lib/copy_user_64.S | 3 + arch/x86/lib/getuser.S | 5 + arch/x86/lib/usercopy_32.c | 8 +- include/linux/fdtable.h | 7 +- include/linux/nospec.h | 92 ++++++++++++++++++++++++ kernel/Kconfig.nospec | 46 ++++++++++++ kernel/Makefile | 1 kernel/nospec.c | 52 +++++++++++++ lib/Kconfig | 3 + 21 files changed, 484 insertions(+), 20 deletions(-) create mode 100644 Documentation/speculation.txt create mode 100644 include/linux/nospec.h create mode 100644 kernel/Kconfig.nospec create mode 100644 kernel/nospec.c