Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753847AbeAMSZj (ORCPT + 1 other); Sat, 13 Jan 2018 13:25:39 -0500 Received: from mga17.intel.com ([192.55.52.151]:44339 "EHLO mga17.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751475AbeAMSZh (ORCPT ); Sat, 13 Jan 2018 13:25:37 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,354,1511856000"; d="scan'208";a="9514764" Subject: [PATCH v3 0/9] core, x86: prevent bounds-check bypass via speculative execution From: Dan Williams To: linux-kernel@vger.kernel.org Cc: Mark Rutland , kernel-hardening@lists.openwall.com, Peter Zijlstra , Catalin Marinas , Will Deacon , "H. Peter Anvin" , Elena Reshetova , linux-arch@vger.kernel.org, Andi Kleen , Jonathan Corbet , x86@kernel.org, Russell King , Ingo Molnar , Alan Cox , Tom Lendacky , Kees Cook , Al Viro , tglx@linutronix.de, alan@linux.intel.com, gregkh@linuxfoundation.org, akpm@linux-foundation.org, torvalds@linux-foundation.org Date: Sat, 13 Jan 2018 10:17:22 -0800 Message-ID: <151586744180.5820.13215059696964205856.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.17.1-9-g687f MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: 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