From: Greg Kroah-Hartman Date: Thu, 23 Feb 2023 09:47:38 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v6.2.1~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9bf45ea8bbd19399b78de0ea6a174e7c973f5039;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: uaccess-add-speculation-barrier-to-copy_from_user.patch --- diff --git a/queue-4.19/series b/queue-4.19/series index 8b5b3fef426..9810296b908 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -6,3 +6,4 @@ powerpc-dts-t208x-disable-10g-on-mac1-and-mac2.patch alarmtimer-prevent-starvation-by-small-intervals-and-sig_ign.patch drm-i915-gvt-fix-double-free-bug-in-split_2mb_gtt_entry.patch mac80211-mesh-embedd-mesh_paths-and-mpp_paths-into-ieee80211_if_mesh.patch +uaccess-add-speculation-barrier-to-copy_from_user.patch diff --git a/queue-4.19/uaccess-add-speculation-barrier-to-copy_from_user.patch b/queue-4.19/uaccess-add-speculation-barrier-to-copy_from_user.patch new file mode 100644 index 00000000000..70012c6f3aa --- /dev/null +++ b/queue-4.19/uaccess-add-speculation-barrier-to-copy_from_user.patch @@ -0,0 +1,105 @@ +From 74e19ef0ff8061ef55957c3abd71614ef0f42f47 Mon Sep 17 00:00:00 2001 +From: Dave Hansen +Date: Tue, 21 Feb 2023 12:30:15 -0800 +Subject: uaccess: Add speculation barrier to copy_from_user() + +From: Dave Hansen + +commit 74e19ef0ff8061ef55957c3abd71614ef0f42f47 upstream. + +The results of "access_ok()" can be mis-speculated. The result is that +you can end speculatively: + + if (access_ok(from, size)) + // Right here + +even for bad from/size combinations. On first glance, it would be ideal +to just add a speculation barrier to "access_ok()" so that its results +can never be mis-speculated. + +But there are lots of system calls just doing access_ok() via +"copy_to_user()" and friends (example: fstat() and friends). Those are +generally not problematic because they do not _consume_ data from +userspace other than the pointer. They are also very quick and common +system calls that should not be needlessly slowed down. + +"copy_from_user()" on the other hand uses a user-controller pointer and +is frequently followed up with code that might affect caches. Take +something like this: + + if (!copy_from_user(&kernelvar, uptr, size)) + do_something_with(kernelvar); + +If userspace passes in an evil 'uptr' that *actually* points to a kernel +addresses, and then do_something_with() has cache (or other) +side-effects, it could allow userspace to infer kernel data values. + +Add a barrier to the common copy_from_user() code to prevent +mis-speculated values which happen after the copy. + +Also add a stub for architectures that do not define barrier_nospec(). +This makes the macro usable in generic code. + +Since the barrier is now usable in generic code, the x86 #ifdef in the +BPF code can also go away. + +Reported-by: Jordy Zomer +Suggested-by: Linus Torvalds +Signed-off-by: Dave Hansen +Reviewed-by: Thomas Gleixner +Acked-by: Daniel Borkmann # BPF bits +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/nospec.h | 4 ++++ + kernel/bpf/core.c | 2 -- + lib/usercopy.c | 7 +++++++ + 3 files changed, 11 insertions(+), 2 deletions(-) + +--- a/include/linux/nospec.h ++++ b/include/linux/nospec.h +@@ -9,6 +9,10 @@ + + struct task_struct; + ++#ifndef barrier_nospec ++# define barrier_nospec() do { } while (0) ++#endif ++ + /** + * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise + * @index: array element index +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1373,9 +1373,7 @@ out: + * reuse preexisting logic from Spectre v1 mitigation that + * happens to produce the required code on x86 for v4 as well. + */ +-#ifdef CONFIG_X86 + barrier_nospec(); +-#endif + CONT; + #define LDST(SIZEOP, SIZE) \ + STX_MEM_##SIZEOP: \ +--- a/lib/usercopy.c ++++ b/lib/usercopy.c +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + #include ++#include + + /* out-of-line parts */ + +@@ -9,6 +10,12 @@ unsigned long _copy_from_user(void *to, + unsigned long res = n; + might_fault(); + if (likely(access_ok(VERIFY_READ, from, n))) { ++ /* ++ * Ensure that bad access_ok() speculation will not ++ * lead to nasty side effects *after* the copy is ++ * finished: ++ */ ++ barrier_nospec(); + kasan_check_write(to, n); + res = raw_copy_from_user(to, from, n); + }