[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <151586744180.5820.13215059696964205856.stgit@dwillia2-desk3.amr.corp.intel.com>
Date: Sat, 13 Jan 2018 10:17:22 -0800
From: Dan Williams <dan.j.williams@...el.com>
To: linux-kernel@...r.kernel.org
Cc: Mark Rutland <mark.rutland@....com>,
kernel-hardening@...ts.openwall.com,
Peter Zijlstra <peterz@...radead.org>,
Catalin Marinas <catalin.marinas@....com>,
Will Deacon <will.deacon@....com>,
"H. Peter Anvin" <hpa@...or.com>,
Elena Reshetova <elena.reshetova@...el.com>,
linux-arch@...r.kernel.org, Andi Kleen <ak@...ux.intel.com>,
Jonathan Corbet <corbet@....net>, x86@...nel.org,
Russell King <linux@...linux.org.uk>,
Ingo Molnar <mingo@...hat.com>, Alan Cox <alan.cox@...el.com>,
Tom Lendacky <thomas.lendacky@....com>,
Kees Cook <keescook@...omium.org>,
Al Viro <viro@...iv.linux.org.uk>, tglx@...utronix.de,
alan@...ux.intel.com, gregkh@...uxfoundation.org,
akpm@...ux-foundation.org, torvalds@...ux-foundation.org
Subject: [PATCH v3 0/9] core,
x86: prevent bounds-check bypass via speculative execution
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
Powered by blists - more mailing lists