Patch "array_index_nospec: Sanitize speculative array de-references" has been added to the 4.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    array_index_nospec: Sanitize speculative array de-references

to the 4.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     array_index_nospec-sanitize-speculative-array-de-references.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.


>From foo@baz Fri Feb 23 17:23:58 CET 2018
From: Jack Wang <jinpu.wang@xxxxxxxxxxxxxxxx>
Date: Fri, 23 Feb 2018 11:42:00 +0100
Subject: array_index_nospec: Sanitize speculative array de-references
To: gregkh@xxxxxxxxxxxxxxxxxxx, stable@xxxxxxxxxxxxxxx
Cc: Dan Williams <dan.j.williams@xxxxxxxxx>, Thomas Gleixner <tglx@xxxxxxxxxxxxx>, linux-arch@xxxxxxxxxxxxxxx, kernel-hardening@xxxxxxxxxxxxxxxxxx, Peter Zijlstra <peterz@xxxxxxxxxxxxx>, Catalin Marinas <catalin.marinas@xxxxxxx>, Will Deacon <will.deacon@xxxxxxx>, Russell King <linux@xxxxxxxxxxxxxxx>, torvalds@xxxxxxxxxxxxxxxxxxxx, alan@xxxxxxxxxxxxxxx, David Woodhouse <dwmw@xxxxxxxxxxxx>, Jack Wang <jinpu.wang@xxxxxxxxxxxxxxxx>
Message-ID: <1519382538-15143-12-git-send-email-jinpu.wangl@xxxxxxxxxxxxxxxx>

From: Dan Williams <dan.j.williams@xxxxxxxxx>

(cherry picked from commit f3804203306e098dae9ca51540fcd5eb700d7f40)

array_index_nospec() is proposed as a generic mechanism to mitigate
against Spectre-variant-1 attacks, i.e. an attack that bypasses boundary
checks via speculative execution. The array_index_nospec()
implementation is expected to be safe for current generation CPUs across
multiple architectures (ARM, x86).

Based on an original implementation by Linus Torvalds, tweaked to remove
speculative flows by Alexei Starovoitov, and tweaked again by Linus to
introduce an x86 assembly implementation for the mask generation.

Co-developed-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Co-developed-by: Alexei Starovoitov <ast@xxxxxxxxxx>
Suggested-by: Cyril Novikov <cnovikov@xxxxxxxx>
Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: linux-arch@xxxxxxxxxxxxxxx
Cc: kernel-hardening@xxxxxxxxxxxxxxxxxx
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Catalin Marinas <catalin.marinas@xxxxxxx>
Cc: Will Deacon <will.deacon@xxxxxxx>
Cc: Russell King <linux@xxxxxxxxxxxxxxx>
Cc: gregkh@xxxxxxxxxxxxxxxxxxx
Cc: torvalds@xxxxxxxxxxxxxxxxxxxx
Cc: alan@xxxxxxxxxxxxxxx
Link: https://lkml.kernel.org/r/151727414229.33451.18411580953862676575.stgit@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
[jwang: cherry pick to 4.4]
Signed-off-by: Jack Wang <jinpu.wang@xxxxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 include/linux/nospec.h |   72 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 include/linux/nospec.h

--- /dev/null
+++ b/include/linux/nospec.h
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Linus Torvalds. All rights reserved.
+// Copyright(c) 2018 Alexei Starovoitov. All rights reserved.
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#ifndef _LINUX_NOSPEC_H
+#define _LINUX_NOSPEC_H
+
+/**
+ * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise
+ * @index: array element index
+ * @size: number of elements in array
+ *
+ * When @index is out of bounds (@index >= @size), the sign bit will be
+ * set.  Extend the sign bit to all bits and invert, giving a result of
+ * zero for an out of bounds index, or ~0 if within bounds [0, @size).
+ */
+#ifndef array_index_mask_nospec
+static inline unsigned long array_index_mask_nospec(unsigned long index,
+						    unsigned long size)
+{
+	/*
+	 * Warn developers about inappropriate array_index_nospec() usage.
+	 *
+	 * Even if the CPU speculates past the WARN_ONCE branch, the
+	 * sign bit of @index is taken into account when generating the
+	 * mask.
+	 *
+	 * This warning is compiled out when the compiler can infer that
+	 * @index and @size are less than LONG_MAX.
+	 */
+	if (WARN_ONCE(index > LONG_MAX || size > LONG_MAX,
+			"array_index_nospec() limited to range of [0, LONG_MAX]\n"))
+		return 0;
+
+	/*
+	 * Always calculate and emit the mask even if the compiler
+	 * thinks the mask is not needed. The compiler does not take
+	 * into account the value of @index under speculation.
+	 */
+	OPTIMIZER_HIDE_VAR(index);
+	return ~(long)(index | (size - 1UL - index)) >> (BITS_PER_LONG - 1);
+}
+#endif
+
+/*
+ * array_index_nospec - sanitize an array index after a bounds check
+ *
+ * For a code sequence like:
+ *
+ *     if (index < size) {
+ *         index = array_index_nospec(index, size);
+ *         val = array[index];
+ *     }
+ *
+ * ...if the CPU speculates past the bounds check then
+ * array_index_nospec() will clamp the index within the range of [0,
+ * size).
+ */
+#define array_index_nospec(index, size)					\
+({									\
+	typeof(index) _i = (index);					\
+	typeof(size) _s = (size);					\
+	unsigned long _mask = array_index_mask_nospec(_i, _s);		\
+									\
+	BUILD_BUG_ON(sizeof(_i) > sizeof(long));			\
+	BUILD_BUG_ON(sizeof(_s) > sizeof(long));			\
+									\
+	_i &= _mask;							\
+	_i;								\
+})
+#endif /* _LINUX_NOSPEC_H */


Patches currently in stable-queue which might be from jinpu.wang@xxxxxxxxxxxxxxxx are

queue-4.4/x86-paravirt-remove-noreplace-paravirt-cmdline-option.patch
queue-4.4/documentation-document-array_index_nospec.patch
queue-4.4/kvm-x86-make-indirect-calls-in-emulator-speculation-safe.patch
queue-4.4/x86-nospec-fix-header-guards-names.patch
queue-4.4/x86-retpoline-avoid-retpolines-for-built-in-__init-functions.patch
queue-4.4/vfs-fdtable-prevent-bounds-check-bypass-via-speculative-execution.patch
queue-4.4/kvm-nvmx-invvpid-handling-improvements.patch
queue-4.4/x86-cpu-bugs-make-retpoline-module-warning-conditional.patch
queue-4.4/x86-spectre-check-config_retpoline-in-command-line-parser.patch
queue-4.4/x86-implement-array_index_mask_nospec.patch
queue-4.4/array_index_nospec-sanitize-speculative-array-de-references.patch
queue-4.4/kvm-vmx-make-indirect-call-speculation-safe.patch
queue-4.4/x86-spectre-fix-spelling-mistake-vunerable-vulnerable.patch
queue-4.4/kvm-nvmx-fix-kernel-panics-induced-by-illegal-invept-invvpid-types.patch
queue-4.4/module-retpoline-warn-about-missing-retpoline-in-module.patch
queue-4.4/x86-kvm-update-spectre-v1-mitigation.patch
queue-4.4/x86-get_user-use-pointer-masking-to-limit-speculation.patch
queue-4.4/x86-syscall-sanitize-syscall-table-de-references-under-speculation.patch
queue-4.4/kvm-nvmx-vmx_complete_nested_posted_interrupt-can-t-fail.patch
queue-4.4/x86-spectre-simplify-spectre_v2-command-line-parsing.patch
queue-4.4/x86-speculation-fix-typo-ibrs_att-which-should-be-ibrs_all.patch
queue-4.4/x86-spectre-report-get_user-mitigation-for-spectre_v1.patch
queue-4.4/x86-introduce-barrier_nospec.patch
queue-4.4/kvm-async_pf-fix-df-due-to-inject-page-not-present-and-page-ready-exceptions-simultaneously.patch
queue-4.4/kvm-vmx-clean-up-declaration-of-vpid-ept-invalidation-types.patch
queue-4.4/x86-bugs-drop-one-mitigation-from-dmesg.patch
queue-4.4/x86-retpoline-remove-the-esp-rsp-thunk.patch
queue-4.4/nl80211-sanitize-array-index-in-parse_txq_params.patch
queue-4.4/kvm-nvmx-kmap-can-t-fail.patch



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]