diff --git a/kernel.spec b/kernel.spec index 760285d44..ebff58b65 100644 --- a/kernel.spec +++ b/kernel.spec @@ -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 - 4.15.2-300 +- Linux v4.15.2 + * Tue Feb 06 2018 Laura Abbott - 4.15.1-300 - Linux v4.15.1 diff --git a/prevent-bounds-check-bypass-via-speculative-execution.patch b/prevent-bounds-check-bypass-via-speculative-execution.patch index 890efc149..275d3b039 100644 --- a/prevent-bounds-check-bypass-via-speculative-execution.patch +++ b/prevent-bounds-check-bypass-via-speculative-execution.patch @@ -105,199 +105,6 @@ index fe297b599b0a..91c3071f49e5 100644 -- 2.14.3 -From 0a9659964052448903985b38f08b3912ab65f1a9 Mon Sep 17 00:00:00 2001 -From: Mark Rutland -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 -Signed-off-by: Will Deacon -Cc: Dan Williams -Cc: Jonathan Corbet -Cc: Peter Zijlstra -Signed-off-by: Dan Williams ---- - 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 , #MAX_ARRAY_ELEMS -+ B.LT less -+ MOV , #0 -+ RET -+ less: -+ LDR , [, ] -+ 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 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 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 -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 -Suggested-by: Arjan van de Ven -Suggested-by: Alan Cox -Cc: Mark Rutland -Cc: Greg KH -Cc: Thomas Gleixner -Cc: Alan Cox -Signed-off-by: Elena Reshetova -Signed-off-by: Dan Williams ---- - 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 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 -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 -Signed-off-by: Elena Reshetova -Signed-off-by: Dan Williams ---- - 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 Date: Wed, 3 Jan 2018 13:54:05 -0800 diff --git a/sources b/sources index e86f6ad5b..0a3ef88dd 100644 --- a/sources +++ b/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