Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sat, 13 Jan 2018 10:17:22 -0800
From: Dan Williams <>
Cc: Mark Rutland <>,,
 Peter Zijlstra <>,
 Catalin Marinas <>, Will Deacon <>,
 "H. Peter Anvin" <>, Elena Reshetova <>,, Andi Kleen <>,
 Jonathan Corbet <>,,
 Russell King <>, Ingo Molnar <>,
 Alan Cox <>, Tom Lendacky <>,
 Kees Cook <>, Al Viro <>,,,,,
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

* include the get_user_{1,2,4,8} helpers in the ASM_IFENCE protections

* fix array_ptr_mask for ARCH=i386 builds (Kbuild robot)

* prioritize the get_user protections, and the fdtable fix



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)

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
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:// nospec-v3

Note that the BPF fix for Spectre variant1 is merged for 4.15-rc8.



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

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.