Skip to content

Commit ac41e90

Browse files
bp3tk0vgregkh
authored andcommitted
x86/srso: Add a Speculative RAS Overflow mitigation
Upstream commit: fb3bd91 Add a mitigation for the speculative return address stack overflow vulnerability found on AMD processors. 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_untrain_ret_alias() and the safe return function srso_safe_ret_alias() 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(). Signed-off-by: Borislav Petkov (AMD) <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent dec3b91 commit ac41e90

File tree

16 files changed

+420
-9
lines changed

16 files changed

+420
-9
lines changed

Documentation/admin-guide/hw-vuln/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ are configurable at compile, boot or run time.
2020
processor_mmio_stale_data.rst
2121
cross-thread-rsb.rst
2222
gather_data_sampling.rst
23+
srso
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
Speculative Return Stack Overflow (SRSO)
4+
========================================
5+
6+
This is a mitigation for the speculative return stack overflow (SRSO)
7+
vulnerability found on AMD processors. The mechanism is by now the well
8+
known scenario of poisoning CPU functional units - the Branch Target
9+
Buffer (BTB) and Return Address Predictor (RAP) in this case - and then
10+
tricking the elevated privilege domain (the kernel) into leaking
11+
sensitive data.
12+
13+
AMD CPUs predict RET instructions using a Return Address Predictor (aka
14+
Return Address Stack/Return Stack Buffer). In some cases, a non-architectural
15+
CALL instruction (i.e., an instruction predicted to be a CALL but is
16+
not actually a CALL) can create an entry in the RAP which may be used
17+
to predict the target of a subsequent RET instruction.
18+
19+
The specific circumstances that lead to this varies by microarchitecture
20+
but the concern is that an attacker can mis-train the CPU BTB to predict
21+
non-architectural CALL instructions in kernel space and use this to
22+
control the speculative target of a subsequent kernel RET, potentially
23+
leading to information disclosure via a speculative side-channel.
24+
25+
The issue is tracked under CVE-2023-20569.
26+
27+
Affected processors
28+
-------------------
29+
30+
AMD Zen, generations 1-4. That is, all families 0x17 and 0x19. Older
31+
processors have not been investigated.
32+
33+
System information and options
34+
------------------------------
35+
36+
First of all, it is required that the latest microcode be loaded for
37+
mitigations to be effective.
38+
39+
The sysfs file showing SRSO mitigation status is:
40+
41+
/sys/devices/system/cpu/vulnerabilities/spec_rstack_overflow
42+
43+
The possible values in this file are:
44+
45+
- 'Not affected' The processor is not vulnerable
46+
47+
- 'Vulnerable: no microcode' The processor is vulnerable, no
48+
microcode extending IBPB functionality
49+
to address the vulnerability has been
50+
applied.
51+
52+
- 'Mitigation: microcode' Extended IBPB functionality microcode
53+
patch has been applied. It does not
54+
address User->Kernel and Guest->Host
55+
transitions protection but it does
56+
address User->User and VM->VM attack
57+
vectors.
58+
59+
(spec_rstack_overflow=microcode)
60+
61+
- 'Mitigation: safe RET' Software-only mitigation. It complements
62+
the extended IBPB microcode patch
63+
functionality by addressing User->Kernel
64+
and Guest->Host transitions protection.
65+
66+
Selected by default or by
67+
spec_rstack_overflow=safe-ret
68+
69+
- 'Mitigation: IBPB' Similar protection as "safe RET" above
70+
but employs an IBPB barrier on privilege
71+
domain crossings (User->Kernel,
72+
Guest->Host).
73+
74+
(spec_rstack_overflow=ibpb)
75+
76+
- 'Mitigation: IBPB on VMEXIT' Mitigation addressing the cloud provider
77+
scenario - the Guest->Host transitions
78+
only.
79+
80+
(spec_rstack_overflow=ibpb-vmexit)
81+
82+
In order to exploit vulnerability, an attacker needs to:
83+
84+
- gain local access on the machine
85+
86+
- break kASLR
87+
88+
- find gadgets in the running kernel in order to use them in the exploit
89+
90+
- potentially create and pin an additional workload on the sibling
91+
thread, depending on the microarchitecture (not necessary on fam 0x19)
92+
93+
- run the exploit
94+
95+
Considering the performance implications of each mitigation type, the
96+
default one is 'Mitigation: safe RET' which should take care of most
97+
attack vectors, including the local User->Kernel one.
98+
99+
As always, the user is advised to keep her/his system up-to-date by
100+
applying software updates regularly.
101+
102+
The default setting will be reevaluated when needed and especially when
103+
new attack vectors appear.
104+
105+
As one can surmise, 'Mitigation: safe RET' does come at the cost of some
106+
performance depending on the workload. If one trusts her/his userspace
107+
and does not want to suffer the performance impact, one can always
108+
disable the mitigation with spec_rstack_overflow=off.
109+
110+
Similarly, 'Mitigation: IBPB' is another full mitigation type employing
111+
an indrect branch prediction barrier after having applied the required
112+
microcode patch for one's system. This mitigation comes also at
113+
a performance cost.
114+
115+
Mitigation: safe RET
116+
--------------------
117+
118+
The mitigation works by ensuring all RET instructions speculate to
119+
a controlled location, similar to how speculation is controlled in the
120+
retpoline sequence. To accomplish this, the __x86_return_thunk forces
121+
the CPU to mispredict every function return using a 'safe return'
122+
sequence.
123+
124+
To ensure the safety of this mitigation, the kernel must ensure that the
125+
safe return sequence is itself free from attacker interference. In Zen3
126+
and Zen4, this is accomplished by creating a BTB alias between the
127+
untraining function srso_untrain_ret_alias() and the safe return
128+
function srso_safe_ret_alias() which results in evicting a potentially
129+
poisoned BTB entry and using that safe one for all function returns.
130+
131+
In older Zen1 and Zen2, this is accomplished using a reinterpretation
132+
technique similar to Retbleed one: srso_untrain_ret() and
133+
srso_safe_ret().

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5785,6 +5785,17 @@
57855785
Not specifying this option is equivalent to
57865786
spectre_v2_user=auto.
57875787

5788+
spec_rstack_overflow=
5789+
[X86] Control RAS overflow mitigation on AMD Zen CPUs
5790+
5791+
off - Disable mitigation
5792+
microcode - Enable microcode mitigation only
5793+
safe-ret - Enable sw-only safe RET mitigation (default)
5794+
ibpb - Enable mitigation by issuing IBPB on
5795+
kernel entry
5796+
ibpb-vmexit - Issue IBPB only on VMEXIT
5797+
(cloud-specific mitigation)
5798+
57885799
spec_store_bypass_disable=
57895800
[HW] Control Speculative Store Bypass (SSB) Disable mitigation
57905801
(Speculative Store Bypass vulnerability)

arch/x86/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,6 +2512,13 @@ config CPU_IBRS_ENTRY
25122512
This mitigates both spectre_v2 and retbleed at great cost to
25132513
performance.
25142514

2515+
config CPU_SRSO
2516+
bool "Mitigate speculative RAS overflow on AMD"
2517+
depends on CPU_SUP_AMD && X86_64 && RETHUNK
2518+
default y
2519+
help
2520+
Enable the SRSO mitigation needed on AMD Zen1-4 machines.
2521+
25152522
config SLS
25162523
bool "Mitigate Straight-Line-Speculation"
25172524
depends on CC_HAS_SLS && X86_64

arch/x86/include/asm/cpufeatures.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@
308308

309309
#define X86_FEATURE_MSR_TSX_CTRL (11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */
310310

311+
#define X86_FEATURE_SRSO (11*32+24) /* "" AMD BTB untrain RETs */
312+
#define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */
313+
311314
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
312315
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
313316
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
@@ -466,4 +469,6 @@
466469
#define X86_BUG_SMT_RSB X86_BUG(29) /* CPU is vulnerable to Cross-Thread Return Address Predictions */
467470
#define X86_BUG_GDS X86_BUG(30) /* CPU is affected by Gather Data Sampling */
468471

472+
/* BUG word 2 */
473+
#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */
469474
#endif /* _ASM_X86_CPUFEATURES_H */

arch/x86/include/asm/nospec-branch.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
* eventually turn into it's own annotation.
113113
*/
114114
.macro ANNOTATE_UNRET_END
115-
#ifdef CONFIG_DEBUG_ENTRY
115+
#if (defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO))
116116
ANNOTATE_RETPOLINE_SAFE
117117
nop
118118
#endif
@@ -191,6 +191,11 @@
191191
CALL_ZEN_UNTRAIN_RET, X86_FEATURE_UNRET, \
192192
"call entry_ibpb", X86_FEATURE_ENTRY_IBPB
193193
#endif
194+
195+
#ifdef CONFIG_CPU_SRSO
196+
ALTERNATIVE_2 "", "call srso_untrain_ret", X86_FEATURE_SRSO, \
197+
"call srso_untrain_ret_alias", X86_FEATURE_SRSO_ALIAS
198+
#endif
194199
.endm
195200

196201
#else /* __ASSEMBLY__ */
@@ -206,6 +211,8 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
206211

207212
extern void __x86_return_thunk(void);
208213
extern void zen_untrain_ret(void);
214+
extern void srso_untrain_ret(void);
215+
extern void srso_untrain_ret_alias(void);
209216
extern void entry_ibpb(void);
210217

211218
#ifdef CONFIG_RETPOLINE

arch/x86/include/asm/processor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,9 +800,11 @@ extern u16 get_llc_id(unsigned int cpu);
800800
#ifdef CONFIG_CPU_SUP_AMD
801801
extern u32 amd_get_nodes_per_socket(void);
802802
extern u32 amd_get_highest_perf(void);
803+
extern bool cpu_has_ibpb_brtype_microcode(void);
803804
#else
804805
static inline u32 amd_get_nodes_per_socket(void) { return 0; }
805806
static inline u32 amd_get_highest_perf(void) { return 0; }
807+
static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; }
806808
#endif
807809

808810
#define for_each_possible_hypervisor_cpuid_base(function) \

arch/x86/kernel/alternative.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,9 @@ static int patch_return(void *addr, struct insn *insn, u8 *bytes)
538538
{
539539
int i = 0;
540540

541-
if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
541+
if (cpu_feature_enabled(X86_FEATURE_RETHUNK) ||
542+
cpu_feature_enabled(X86_FEATURE_SRSO) ||
543+
cpu_feature_enabled(X86_FEATURE_SRSO_ALIAS))
542544
return -1;
543545

544546
bytes[i++] = RET_INSN_OPCODE;

arch/x86/kernel/cpu/amd.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,20 @@ u32 amd_get_highest_perf(void)
12451245
}
12461246
EXPORT_SYMBOL_GPL(amd_get_highest_perf);
12471247

1248+
bool cpu_has_ibpb_brtype_microcode(void)
1249+
{
1250+
u8 fam = boot_cpu_data.x86;
1251+
1252+
if (fam == 0x17) {
1253+
/* Zen1/2 IBPB flushes branch type predictions too. */
1254+
return boot_cpu_has(X86_FEATURE_AMD_IBPB);
1255+
} else if (fam == 0x19) {
1256+
return false;
1257+
}
1258+
1259+
return false;
1260+
}
1261+
12481262
static void zenbleed_check_cpu(void *unused)
12491263
{
12501264
struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());

0 commit comments

Comments
 (0)