Linux v4.15.2
This commit is contained in:
parent
b330fa1ca6
commit
7d40e4a029
|
@ -54,7 +54,7 @@ Summary: The Linux kernel
|
|||
%if 0%{?released_kernel}
|
||||
|
||||
# Do we have a -stable update to apply?
|
||||
%define stable_update 1
|
||||
%define stable_update 2
|
||||
# Set rpm version accordingly
|
||||
%if 0%{?stable_update}
|
||||
%define stablerev %{stable_update}
|
||||
|
@ -1909,6 +1909,9 @@ fi
|
|||
#
|
||||
#
|
||||
%changelog
|
||||
* Wed Feb 07 2018 Laura Abbott <labbott@redhat.com> - 4.15.2-300
|
||||
- Linux v4.15.2
|
||||
|
||||
* Tue Feb 06 2018 Laura Abbott <labbott@redhat.com> - 4.15.1-300
|
||||
- Linux v4.15.1
|
||||
|
||||
|
|
|
@ -105,199 +105,6 @@ index fe297b599b0a..91c3071f49e5 100644
|
|||
--
|
||||
2.14.3
|
||||
|
||||
From 0a9659964052448903985b38f08b3912ab65f1a9 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Rutland <mark.rutland@arm.com>
|
||||
Date: Wed, 3 Jan 2018 19:47:06 +0000
|
||||
Subject: [PATCH 02/19] Documentation: document nospec helpers
|
||||
|
||||
Document the rationale and usage of the new nospec*() helpers.
|
||||
|
||||
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
|
||||
Signed-off-by: Will Deacon <will.deacon@arm.com>
|
||||
Cc: Dan Williams <dan.j.williams@intel.com>
|
||||
Cc: Jonathan Corbet <corbet@lwn.net>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
|
||||
---
|
||||
Documentation/speculation.txt | 166 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 166 insertions(+)
|
||||
create mode 100644 Documentation/speculation.txt
|
||||
|
||||
diff --git a/Documentation/speculation.txt b/Documentation/speculation.txt
|
||||
new file mode 100644
|
||||
index 000000000000..748fcd4dcda4
|
||||
--- /dev/null
|
||||
+++ b/Documentation/speculation.txt
|
||||
@@ -0,0 +1,166 @@
|
||||
+This document explains potential effects of speculation, and how undesirable
|
||||
+effects can be mitigated portably using common APIs.
|
||||
+
|
||||
+===========
|
||||
+Speculation
|
||||
+===========
|
||||
+
|
||||
+To improve performance and minimize average latencies, many contemporary CPUs
|
||||
+employ speculative execution techniques such as branch prediction, performing
|
||||
+work which may be discarded at a later stage.
|
||||
+
|
||||
+Typically speculative execution cannot be observed from architectural state,
|
||||
+such as the contents of registers. However, in some cases it is possible to
|
||||
+observe its impact on microarchitectural state, such as the presence or
|
||||
+absence of data in caches. Such state may form side-channels which can be
|
||||
+observed to extract secret information.
|
||||
+
|
||||
+For example, in the presence of branch prediction, it is possible for bounds
|
||||
+checks to be ignored by code which is speculatively executed. Consider the
|
||||
+following code:
|
||||
+
|
||||
+ int load_array(int *array, unsigned int idx) {
|
||||
+ if (idx >= MAX_ARRAY_ELEMS)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return array[idx];
|
||||
+ }
|
||||
+
|
||||
+Which, on arm64, may be compiled to an assembly sequence such as:
|
||||
+
|
||||
+ CMP <idx>, #MAX_ARRAY_ELEMS
|
||||
+ B.LT less
|
||||
+ MOV <returnval>, #0
|
||||
+ RET
|
||||
+ less:
|
||||
+ LDR <returnval>, [<array>, <idx>]
|
||||
+ RET
|
||||
+
|
||||
+It is possible that a CPU mis-predicts the conditional branch, and
|
||||
+speculatively loads array[idx], even if idx >= MAX_ARRAY_ELEMS. This value
|
||||
+will subsequently be discarded, but the speculated load may affect
|
||||
+microarchitectural state which can be subsequently measured.
|
||||
+
|
||||
+More complex sequences involving multiple dependent memory accesses may result
|
||||
+in sensitive information being leaked. Consider the following code, building on
|
||||
+the prior example:
|
||||
+
|
||||
+ int load_dependent_arrays(int *arr1, int *arr2, int idx) {
|
||||
+ int val1, val2,
|
||||
+
|
||||
+ val1 = load_array(arr1, idx);
|
||||
+ val2 = load_array(arr2, val1);
|
||||
+
|
||||
+ return val2;
|
||||
+ }
|
||||
+
|
||||
+Under speculation, the first call to load_array() may return the value of an
|
||||
+out-of-bounds address, while the second call will influence microarchitectural
|
||||
+state dependent on this value. This may provide an arbitrary read primitive.
|
||||
+
|
||||
+====================================
|
||||
+Mitigating speculation side-channels
|
||||
+====================================
|
||||
+
|
||||
+The kernel provides a generic API to ensure that bounds checks are respected
|
||||
+even under speculation. Architectures which are affected by speculation-based
|
||||
+side-channels are expected to implement these primitives.
|
||||
+
|
||||
+The following helpers found in <asm/barrier.h> can be used to prevent
|
||||
+information from being leaked via side-channels.
|
||||
+
|
||||
+* nospec_ptr(ptr, lo, hi)
|
||||
+
|
||||
+ Returns a sanitized pointer that is bounded by the [lo, hi) interval. When
|
||||
+ ptr < lo, or ptr >= hi, NULL is returned. Prevents an out-of-bounds pointer
|
||||
+ being propagated to code which is speculatively executed.
|
||||
+
|
||||
+ This is expected to be used by code which computes pointers to data
|
||||
+ structures, where part of the address (such as an array index) may be
|
||||
+ user-controlled.
|
||||
+
|
||||
+ This can be used to protect the earlier load_array() example:
|
||||
+
|
||||
+ int load_array(int *array, unsigned int idx)
|
||||
+ {
|
||||
+ int *elem;
|
||||
+
|
||||
+ if ((elem = nospec_ptr(array + idx, array, array + MAX_ARRAY_ELEMS)))
|
||||
+ return *elem;
|
||||
+ else
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ This can also be used in situations where multiple fields on a structure are
|
||||
+ accessed:
|
||||
+
|
||||
+ struct foo array[SIZE];
|
||||
+ int a, b;
|
||||
+
|
||||
+ void do_thing(int idx)
|
||||
+ {
|
||||
+ struct foo *elem;
|
||||
+
|
||||
+ if ((elem = nospec_ptr(array + idx, array, array + SIZE)) {
|
||||
+ a = elem->field_a;
|
||||
+ b = elem->field_b;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ It is imperative that the returned pointer is used. Pointers which are
|
||||
+ generated separately are subject to a number of potential CPU and compiler
|
||||
+ optimizations, and may still be used speculatively. For example, this means
|
||||
+ that the following sequence is unsafe:
|
||||
+
|
||||
+ struct foo array[SIZE];
|
||||
+ int a, b;
|
||||
+
|
||||
+ void do_thing(int idx)
|
||||
+ {
|
||||
+ if (nospec_ptr(array + idx, array, array + SIZE) != NULL) {
|
||||
+ // unsafe as wrong pointer is used
|
||||
+ a = array[idx].field_a;
|
||||
+ b = array[idx].field_b;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ Similarly, it is unsafe to compare the returned pointer with other pointers,
|
||||
+ as this may permit the compiler to substitute one pointer with another,
|
||||
+ permitting speculation. For example, the following sequence is unsafe:
|
||||
+
|
||||
+ struct foo array[SIZE];
|
||||
+ int a, b;
|
||||
+
|
||||
+ void do_thing(int idx)
|
||||
+ {
|
||||
+ struct foo *elem = nospec_ptr(array + idx, array, array + size);
|
||||
+
|
||||
+ // unsafe due to pointer substitution
|
||||
+ if (elem == &array[idx]) {
|
||||
+ a = elem->field_a;
|
||||
+ b = elem->field_b;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+* nospec_array_ptr(arr, idx, sz)
|
||||
+
|
||||
+ Returns a sanitized pointer to arr[idx] only if idx falls in the [0, sz)
|
||||
+ interval. When idx < 0 or idx > sz, NULL is returned. Prevents an
|
||||
+ out-of-bounds pointer being propagated to code which is speculatively
|
||||
+ executed.
|
||||
+
|
||||
+ This is a convenience function which wraps nospec_ptr(), and has the same
|
||||
+ caveats w.r.t. the use of the returned pointer.
|
||||
+
|
||||
+ For example, this may be used as follows:
|
||||
+
|
||||
+ int load_array(int *array, unsigned int idx)
|
||||
+ {
|
||||
+ int *elem;
|
||||
+
|
||||
+ if ((elem = nospec_array_ptr(array, idx, MAX_ARRAY_ELEMS)))
|
||||
+ return *elem;
|
||||
+ else
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
--
|
||||
2.14.3
|
||||
|
||||
From 2b98026ffeeb0b4a06c80fe39bfebd5cef4a8fa6 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Rutland <mark.rutland@arm.com>
|
||||
Date: Thu, 7 Dec 2017 17:15:01 +0000
|
||||
|
@ -487,66 +294,6 @@ index 40f5c410fd8c..6384c90e4b72 100644
|
|||
--
|
||||
2.14.3
|
||||
|
||||
From d14a4150a2f74a068247cf3846405904e21a8d2c Mon Sep 17 00:00:00 2001
|
||||
From: Dan Williams <dan.j.williams@intel.com>
|
||||
Date: Wed, 3 Jan 2018 14:51:58 -0800
|
||||
Subject: [PATCH 05/19] x86: implement nospec_barrier()
|
||||
|
||||
The new speculative execution barrier, nospec_barrier(), ensures
|
||||
that any userspace controllable speculation doesn't cross the boundary.
|
||||
|
||||
Any user observable speculative activity on this CPU thread before this
|
||||
point either completes, reaches a state it can no longer cause an
|
||||
observable activity, or is aborted before instructions after the barrier
|
||||
execute.
|
||||
|
||||
In the x86 case nospec_barrier() resolves to an lfence if
|
||||
X86_FEATURE_LFENCE_RDTSC is present. Other architectures can define
|
||||
their variants.
|
||||
|
||||
Note the expectation is that this barrier is never used directly, at
|
||||
least outside of architecture specific code. It is implied by the
|
||||
nospec_{array_ptr,ptr} macros.
|
||||
|
||||
x86, for now, depends on the barrier for protection while other
|
||||
architectures place their speculation prevention in
|
||||
nospec_{ptr,array_ptr} when a barrier instruction is not available or
|
||||
too heavy-weight. In the x86 case lfence is not a fully serializing
|
||||
instruction so it is not as expensive as other barriers.
|
||||
|
||||
Suggested-by: Peter Zijlstra <peterz@infradead.org>
|
||||
Suggested-by: Arjan van de Ven <arjan@linux.intel.com>
|
||||
Suggested-by: Alan Cox <alan.cox@intel.com>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Greg KH <gregkh@linuxfoundation.org>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: Alan Cox <alan@linux.intel.com>
|
||||
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
|
||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
|
||||
---
|
||||
arch/x86/include/asm/barrier.h | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h
|
||||
index 7fb336210e1b..1148cd9f5ae7 100644
|
||||
--- a/arch/x86/include/asm/barrier.h
|
||||
+++ b/arch/x86/include/asm/barrier.h
|
||||
@@ -24,6 +24,12 @@
|
||||
#define wmb() asm volatile("sfence" ::: "memory")
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * CPUs without LFENCE don't really speculate much. Possibly fall back to IRET-to-self.
|
||||
+ */
|
||||
+#define __nospec_barrier() alternative("", "lfence", X86_FEATURE_LFENCE_RDTSC)
|
||||
+#define nospec_barrier __nospec_barrier
|
||||
+
|
||||
#ifdef CONFIG_X86_PPRO_FENCE
|
||||
#define dma_rmb() rmb()
|
||||
#else
|
||||
--
|
||||
2.14.3
|
||||
|
||||
From d077f11b7fcb697af0c9419cc2273d179e6f51ad Mon Sep 17 00:00:00 2001
|
||||
From: Andi Kleen <ak@linux.intel.com>
|
||||
Date: Thu, 4 Jan 2018 13:36:20 -0800
|
||||
|
@ -1161,47 +908,6 @@ index 125c1eab3eaa..f72b20131a15 100644
|
|||
--
|
||||
2.14.3
|
||||
|
||||
From 07a715cb9cd9e4e8bac7204a2462803bfe7ae259 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Williams <dan.j.williams@intel.com>
|
||||
Date: Wed, 3 Jan 2018 13:54:04 -0800
|
||||
Subject: [PATCH 15/19] vfs, fdtable: prevent bounds-check bypass via
|
||||
speculative execution
|
||||
|
||||
Expectedly, static analysis reports that 'fd' is a user controlled value
|
||||
that is used as a data dependency to read from the 'fdt->fd' array. In
|
||||
order to avoid potential leaks of kernel memory values, block
|
||||
speculative execution of the instruction stream that could issue reads
|
||||
based on an invalid 'file *' returned from __fcheck_files.
|
||||
|
||||
Based on an original patch by Elena Reshetova.
|
||||
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
|
||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
|
||||
---
|
||||
include/linux/fdtable.h | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
|
||||
index 1c65817673db..4a147c5c2533 100644
|
||||
--- a/include/linux/fdtable.h
|
||||
+++ b/include/linux/fdtable.h
|
||||
@@ -81,9 +81,10 @@ struct dentry;
|
||||
static inline struct file *__fcheck_files(struct files_struct *files, unsigned int fd)
|
||||
{
|
||||
struct fdtable *fdt = rcu_dereference_raw(files->fdt);
|
||||
+ struct file __rcu **fdp;
|
||||
|
||||
- if (fd < fdt->max_fds)
|
||||
- return rcu_dereference_raw(fdt->fd[fd]);
|
||||
+ if ((fdp = nospec_array_ptr(fdt->fd, fd, fdt->max_fds)))
|
||||
+ return rcu_dereference_raw(*fdp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
--
|
||||
2.14.3
|
||||
|
||||
From e5ef1fdb08b0d2ae0af3f725a6c4a3394af538fe Mon Sep 17 00:00:00 2001
|
||||
From: Dan Williams <dan.j.williams@intel.com>
|
||||
Date: Wed, 3 Jan 2018 13:54:05 -0800
|
||||
|
|
2
sources
2
sources
|
@ -1,2 +1,2 @@
|
|||
SHA512 (linux-4.15.tar.xz) = c00d92659df815a53dcac7dde145b742b1f20867d380c07cb09ddb3295d6ff10f8931b21ef0b09d7156923a3957b39d74d87c883300173b2e20690d2b4ec35ea
|
||||
SHA512 (patch-4.15.1.xz) = d0ffcf6f8311a9b4cfa42cd07c24429af4e2e735c9a841de2baa206873652a42aa4853f19fecc82a2fcf464a39b7a62249c940287a040c4a310e4d024ae5d55f
|
||||
SHA512 (patch-4.15.2.xz) = 883d36831ab6a785dda071c91502ca4401b4d4602901bb19716a390cf48ef21830ebb309fe77ec1b741519fa799de7e342df5d7689224a2989f2816bbeaded24
|
||||
|
|
Loading…
Reference in New Issue