Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31ebc2fe authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Greg Kroah-Hartman
Browse files

powerpc/64s: flush L1D after user accesses



commit 9a32a7e78bd0cd9a9b6332cbdc345ee5ffd0c5de upstream.

IBM Power9 processors can speculatively operate on data in the L1 cache before
it has been completely validated, via a way-prediction mechanism. It is not possible
for an attacker to determine the contents of impermissible memory using this method,
since these systems implement a combination of hardware and software security measures
to prevent scenarios where protected data could be leaked.

However these measures don't address the scenario where an attacker induces
the operating system to speculatively execute instructions using data that the
attacker controls. This can be used for example to speculatively bypass "kernel
user access prevention" techniques, as discovered by Anthony Steinhauser of
Google's Safeside Project. This is not an attack by itself, but there is a possibility
it could be used in conjunction with side-channels or other weaknesses in the
privileged code to construct an attack.

This issue can be mitigated by flushing the L1 cache between privilege boundaries
of concern. This patch flushes the L1 cache after user accesses.

This is part of the fix for CVE-2020-4788.

Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarDaniel Axtens <dja@axtens.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6b36099d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2561,6 +2561,7 @@
					       tsx_async_abort=off [X86]
					       kvm.nx_huge_pages=off [X86]
					       no_entry_flush [PPC]
					       no_uaccess_flush [PPC]

				Exceptions:
					       This does not have any effect on
@@ -2922,6 +2923,9 @@
	nospec_store_bypass_disable
			[HW] Disable all mitigations for the Speculative Store Bypass vulnerability

	no_uaccess_flush
	                [PPC] Don't flush the L1-D cache after accessing user data.

	noxsave		[BUGS=X86] Disables x86 extended register state save
			and restore using xsave. The kernel will fallback to
			enabling legacy floating-point and sse state.
+22 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H
#define _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H

DECLARE_STATIC_KEY_FALSE(uaccess_flush_key);

/* Prototype for function defined in exceptions-64s.S */
void do_uaccess_flush(void);

static __always_inline void allow_user_access(void __user *to, const void __user *from,
					      unsigned long size)
{
}

static inline void prevent_user_access(void __user *to, const void __user *from,
				       unsigned long size)
{
	if (static_branch_unlikely(&uaccess_flush_key))
		do_uaccess_flush();
}

#endif /* _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H */
+9 −0
Original line number Diff line number Diff line
@@ -205,6 +205,14 @@ label##3: \
	FTR_ENTRY_OFFSET 955b-956b;			\
	.popsection;

#define UACCESS_FLUSH_FIXUP_SECTION			\
959:							\
	.pushsection __uaccess_flush_fixup,"a";		\
	.align 2;					\
960:							\
	FTR_ENTRY_OFFSET 959b-960b;			\
	.popsection;

#define ENTRY_FLUSH_FIXUP_SECTION			\
957:							\
	.pushsection __entry_flush_fixup,"a";		\
@@ -248,6 +256,7 @@ extern long stf_barrier_fallback;
extern long entry_flush_fallback;
extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup;
extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
extern long __start___uaccess_flush_fixup, __stop___uaccess_flush_fixup;
extern long __start___entry_flush_fixup, __stop___entry_flush_fixup;
extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup;
+4 −0
Original line number Diff line number Diff line
@@ -6,10 +6,14 @@

#include <asm/pgtable.h>

#ifdef CONFIG_PPC_BOOK3S_64
#include <asm/book3s/64/kup-radix.h>
#else
static inline void allow_user_access(void __user *to, const void __user *from,
				     unsigned long size) { }
static inline void prevent_user_access(void __user *to, const void __user *from,
				       unsigned long size) { }
#endif /* CONFIG_PPC_BOOK3S_64 */

static inline void allow_read_from_user(const void __user *from, unsigned long size)
{
+3 −0
Original line number Diff line number Diff line
@@ -87,6 +87,8 @@ static inline bool security_ftr_enabled(unsigned long feature)
// The L1-D cache should be flushed when entering the kernel
#define SEC_FTR_L1D_FLUSH_ENTRY		0x0000000000004000ull

// The L1-D cache should be flushed after user accesses from the kernel
#define SEC_FTR_L1D_FLUSH_UACCESS	0x0000000000008000ull

// Features enabled by default
#define SEC_FTR_DEFAULT \
@@ -94,6 +96,7 @@ static inline bool security_ftr_enabled(unsigned long feature)
	 SEC_FTR_L1D_FLUSH_PR | \
	 SEC_FTR_BNDS_CHK_SPEC_BAR | \
	 SEC_FTR_L1D_FLUSH_ENTRY | \
	 SEC_FTR_L1D_FLUSH_UACCESS | \
	 SEC_FTR_FAVOUR_SECURITY)

#endif /* _ASM_POWERPC_SECURITY_FEATURES_H */
Loading