From: Greg Kroah-Hartman Date: Thu, 23 Feb 2023 09:47:47 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v6.2.1~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c0c1d53c1207c425dbe83966966ddb238c1bd325;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: uaccess-add-speculation-barrier-to-copy_from_user.patch --- diff --git a/queue-5.4/series b/queue-5.4/series index 9a665ed93bf..3d18075efe2 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -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 index 00000000000..2246ee30da0 --- /dev/null +++ b/queue-5.4/uaccess-add-speculation-barrier-to-copy_from_user.patch @@ -0,0 +1,106 @@ +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 +@@ -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 + #include ++#include + + /* 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); + }