]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Feb 2023 09:47:47 +0000 (10:47 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Feb 2023 09:47:47 +0000 (10:47 +0100)
added patches:
uaccess-add-speculation-barrier-to-copy_from_user.patch

queue-5.4/series
queue-5.4/uaccess-add-speculation-barrier-to-copy_from_user.patch [new file with mode: 0644]

index 9a665ed93bf514d65e39c8210881e22afe725da8..3d18075efe2f5aef1c369eda42a0307d93ee48a7 100644 (file)
@@ -12,3 +12,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-5.4/uaccess-add-speculation-barrier-to-copy_from_user.patch b/queue-5.4/uaccess-add-speculation-barrier-to-copy_from_user.patch
new file mode 100644 (file)
index 0000000..2246ee3
--- /dev/null
@@ -0,0 +1,106 @@
+From 74e19ef0ff8061ef55957c3abd71614ef0f42f47 Mon Sep 17 00:00:00 2001
+From: Dave Hansen <dave.hansen@linux.intel.com>
+Date: Tue, 21 Feb 2023 12:30:15 -0800
+Subject: uaccess: Add speculation barrier to copy_from_user()
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+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 <jordyzomer@google.com>
+Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>   # BPF bits
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -1567,9 +1567,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,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <linux/uaccess.h>
+ #include <linux/bitops.h>
++#include <linux/nospec.h>
+ /* out-of-line parts */
+@@ -10,6 +11,12 @@ unsigned long _copy_from_user(void *to,
+       unsigned long res = n;
+       might_fault();
+       if (likely(access_ok(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);
+       }