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

Reply via email to