Unverified Commit 81f476f9 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!2326 fix CVE-2023-20569

Merge Pull Request from: @zhangjialin11 
 
New architectural features and CPUID bits related to the
Speculative Return Stack Overflow (SRSO) vulnerability.

https://gitee.com/src-openeuler/kernel/issues/I7RQ67 
 
Link:https://gitee.com/openeuler/kernel/pulls/2326

 

Reviewed-by: default avatarJason Zeng <jason.zeng@intel.com>
Reviewed-by: default avatarXie Haocheng <haocheng.xie@amd.com>
Reviewed-by: default avatarZenghui Yu <yuzenghui@huawei.com>
parents 3c130e24 4c54158e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -19,3 +19,4 @@ are configurable at compile, boot or run time.
   processor_mmio_stale_data.rst
   cross-thread-rsb.rst
   gather_data_sampling.rst
   srso
+133 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

Speculative Return Stack Overflow (SRSO)
========================================

This is a mitigation for the speculative return stack overflow (SRSO)
vulnerability found on AMD processors. The mechanism is by now the well
known scenario of poisoning CPU functional units - the Branch Target
Buffer (BTB) and Return Address Predictor (RAP) in this case - and then
tricking the elevated privilege domain (the kernel) into leaking
sensitive data.

AMD CPUs predict RET instructions using a Return Address Predictor (aka
Return Address Stack/Return Stack Buffer). In some cases, a non-architectural
CALL instruction (i.e., an instruction predicted to be a CALL but is
not actually a CALL) can create an entry in the RAP which may be used
to predict the target of a subsequent RET instruction.

The specific circumstances that lead to this varies by microarchitecture
but the concern is that an attacker can mis-train the CPU BTB to predict
non-architectural CALL instructions in kernel space and use this to
control the speculative target of a subsequent kernel RET, potentially
leading to information disclosure via a speculative side-channel.

The issue is tracked under CVE-2023-20569.

Affected processors
-------------------

AMD Zen, generations 1-4. That is, all families 0x17 and 0x19. Older
processors have not been investigated.

System information and options
------------------------------

First of all, it is required that the latest microcode be loaded for
mitigations to be effective.

The sysfs file showing SRSO mitigation status is:

  /sys/devices/system/cpu/vulnerabilities/spec_rstack_overflow

The possible values in this file are:

 - 'Not affected'               The processor is not vulnerable

 - 'Vulnerable: no microcode'   The processor is vulnerable, no
                                microcode extending IBPB functionality
                                to address the vulnerability has been
                                applied.

 - 'Mitigation: microcode'      Extended IBPB functionality microcode
                                patch has been applied. It does not
                                address User->Kernel and Guest->Host
                                transitions protection but it does
                                address User->User and VM->VM attack
                                vectors.

                                (spec_rstack_overflow=microcode)

 - 'Mitigation: safe RET'       Software-only mitigation. It complements
                                the extended IBPB microcode patch
                                functionality by addressing User->Kernel
                                and Guest->Host transitions protection.

                                Selected by default or by
                                spec_rstack_overflow=safe-ret

 - 'Mitigation: IBPB'           Similar protection as "safe RET" above
                                but employs an IBPB barrier on privilege
                                domain crossings (User->Kernel,
                                Guest->Host).

                                (spec_rstack_overflow=ibpb)

 - 'Mitigation: IBPB on VMEXIT' Mitigation addressing the cloud provider
                                scenario - the Guest->Host transitions
                                only.

                                (spec_rstack_overflow=ibpb-vmexit)

In order to exploit vulnerability, an attacker needs to:

 - gain local access on the machine

 - break kASLR

 - find gadgets in the running kernel in order to use them in the exploit

 - potentially create and pin an additional workload on the sibling
   thread, depending on the microarchitecture (not necessary on fam 0x19)

 - run the exploit

Considering the performance implications of each mitigation type, the
default one is 'Mitigation: safe RET' which should take care of most
attack vectors, including the local User->Kernel one.

As always, the user is advised to keep her/his system up-to-date by
applying software updates regularly.

The default setting will be reevaluated when needed and especially when
new attack vectors appear.

As one can surmise, 'Mitigation: safe RET' does come at the cost of some
performance depending on the workload. If one trusts her/his userspace
and does not want to suffer the performance impact, one can always
disable the mitigation with spec_rstack_overflow=off.

Similarly, 'Mitigation: IBPB' is another full mitigation type employing
an indrect branch prediction barrier after having applied the required
microcode patch for one's system. This mitigation comes also at
a performance cost.

Mitigation: safe RET
--------------------

The mitigation works by ensuring all RET instructions speculate to
a controlled location, similar to how speculation is controlled in the
retpoline sequence.  To accomplish this, the __x86_return_thunk forces
the CPU to mispredict every function return using a 'safe return'
sequence.

To ensure the safety of this mitigation, the kernel must ensure that the
safe return sequence is itself free from attacker interference.  In Zen3
and Zen4, this is accomplished by creating a BTB alias between the
untraining function srso_alias_untrain_ret() and the safe return
function srso_alias_safe_ret() which results in evicting a potentially
poisoned BTB entry and using that safe one for all function returns.

In older Zen1 and Zen2, this is accomplished using a reinterpretation
technique similar to Retbleed one: srso_untrain_ret() and
srso_safe_ret().
+11 −0
Original line number Diff line number Diff line
@@ -5362,6 +5362,17 @@
			Not specifying this option is equivalent to
			spectre_v2_user=auto.

	spec_rstack_overflow=
			[X86] Control RAS overflow mitigation on AMD Zen CPUs

			off		- Disable mitigation
			microcode	- Enable microcode mitigation only
			safe-ret	- Enable sw-only safe RET mitigation (default)
			ibpb		- Enable mitigation by issuing IBPB on
					  kernel entry
			ibpb-vmexit	- Issue IBPB only on VMEXIT
					  (cloud-specific mitigation)

	spec_store_bypass_disable=
			[HW] Control Speculative Store Bypass (SSB) Disable mitigation
			(Speculative Store Bypass vulnerability)
+7 −0
Original line number Diff line number Diff line
@@ -2545,6 +2545,13 @@ config CPU_IBRS_ENTRY
	  This mitigates both spectre_v2 and retbleed at great cost to
	  performance.

config CPU_SRSO
	bool "Mitigate speculative RAS overflow on AMD"
	depends on CPU_SUP_AMD && X86_64 && RETHUNK
	default y
	help
	  Enable the SRSO mitigation needed on AMD Zen1-4 machines.

config SLS
	bool "Mitigate Straight-Line-Speculation"
	depends on CC_HAS_SLS && X86_64
+19 −4
Original line number Diff line number Diff line
@@ -47,10 +47,14 @@ extern const char * const x86_power_flags[32];
 * In order to save room, we index into this array by doing
 * X86_BUG_<name> - NCAPINTS*32.
 */
extern const char * const x86_bug_flags[NBUGINTS*32];
extern const char * const x86_bug_flags[(NBUGINTS+NEXTBUGINTS)*32];

#define IS_EXT_BUGBIT(bit) ((bit>>5) >= (NCAPINTS+NBUGINTS))

#define test_cpu_cap(c, bit)						\
	 arch_test_bit(bit, (unsigned long *)((c)->x86_capability))
	 (IS_EXT_BUGBIT(bit) ? arch_test_bit((bit) - ((NCAPINTS+NBUGINTS)*32), \
				(unsigned long *)((c)->x86_ext_capability)) : \
				arch_test_bit(bit, (unsigned long *)((c)->x86_capability)))

/*
 * There are 32 bits/features in each mask word.  The high bits
@@ -137,13 +141,24 @@ extern const char * const x86_bug_flags[NBUGINTS*32];

#define boot_cpu_has(bit)	cpu_has(&boot_cpu_data, bit)

#define set_cpu_cap(c, bit)	set_bit(bit, (unsigned long *)((c)->x86_capability))
#define set_cpu_cap(c, bit)  do {						  \
	if (IS_EXT_BUGBIT(bit))							  \
		set_bit(bit - ((NCAPINTS+NBUGINTS))*32,				  \
			(unsigned long *)((c)->x86_ext_capability)); \
	else									  \
		set_bit(bit, (unsigned long *)((c)->x86_capability));		  \
} while (0)


extern void setup_clear_cpu_cap(unsigned int bit);
extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);

#define setup_force_cpu_cap(bit) do { \
	set_cpu_cap(&boot_cpu_data, bit);	\
	if (IS_EXT_BUGBIT(bit))    \
		set_bit(bit - ((NCAPINTS+NBUGINTS))*32,				  \
			(unsigned long *)&cpu_caps_set[NCAPINTS+NBUGINTS]);	  \
	else \
		set_bit(bit, (unsigned long *)cpu_caps_set);	\
} while (0)

Loading