Skip to content

Commit 138bcdd

Browse files
committed
Merge tag 'x86_bugs_srso' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86/srso fixes from Borislav Petkov: "Add a mitigation for the speculative RAS (Return Address Stack) overflow vulnerability on AMD processors. In short, this is yet another issue where userspace poisons a microarchitectural structure which can then be used to leak privileged information through a side channel" * tag 'x86_bugs_srso' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/srso: Tie SBPB bit setting to microcode patch detection x86/srso: Add a forgotten NOENDBR annotation x86/srso: Fix return thunks in generated code x86/srso: Add IBPB on VMEXIT x86/srso: Add IBPB x86/srso: Add SRSO_NO support x86/srso: Add IBPB_BRTYPE support x86/srso: Add a Speculative RAS Overflow mitigation x86/bugs: Increase the x86 bugs vector size to two u32s
2 parents 14f9643 + 5a15d83 commit 138bcdd

File tree

20 files changed

+521
-16
lines changed

20 files changed

+521
-16
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ are configurable at compile, boot or run time.
1919
l1d_flush.rst
2020
processor_mmio_stale_data.rst
2121
cross-thread-rsb.rst
22+
srso
+133
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

+11
Original file line numberDiff line numberDiff line change
@@ -5875,6 +5875,17 @@
58755875
Not specifying this option is equivalent to
58765876
spectre_v2_user=auto.
58775877

5878+
spec_rstack_overflow=
5879+
[X86] Control RAS overflow mitigation on AMD Zen CPUs
5880+
5881+
off - Disable mitigation
5882+
microcode - Enable microcode mitigation only
5883+
safe-ret - Enable sw-only safe RET mitigation (default)
5884+
ibpb - Enable mitigation by issuing IBPB on
5885+
kernel entry
5886+
ibpb-vmexit - Issue IBPB only on VMEXIT
5887+
(cloud-specific mitigation)
5888+
58785889
spec_store_bypass_disable=
58795890
[HW] Control Speculative Store Bypass (SSB) Disable mitigation
58805891
(Speculative Store Bypass vulnerability)

arch/x86/Kconfig

+7
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,13 @@ config CPU_IBRS_ENTRY
25932593
This mitigates both spectre_v2 and retbleed at great cost to
25942594
performance.
25952595

2596+
config CPU_SRSO
2597+
bool "Mitigate speculative RAS overflow on AMD"
2598+
depends on CPU_SUP_AMD && X86_64 && RETHUNK
2599+
default y
2600+
help
2601+
Enable the SRSO mitigation needed on AMD Zen1-4 machines.
2602+
25962603
config SLS
25972604
bool "Mitigate Straight-Line-Speculation"
25982605
depends on CC_HAS_SLS && X86_64

arch/x86/include/asm/cpufeatures.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* Defines x86 CPU feature bits
1515
*/
1616
#define NCAPINTS 21 /* N 32-bit words worth of info */
17-
#define NBUGINTS 1 /* N 32-bit bug flags */
17+
#define NBUGINTS 2 /* N 32-bit bug flags */
1818

1919
/*
2020
* Note: If the comment begins with a quoted string, that string is used
@@ -309,6 +309,10 @@
309309
#define X86_FEATURE_SMBA (11*32+21) /* "" Slow Memory Bandwidth Allocation */
310310
#define X86_FEATURE_BMEC (11*32+22) /* "" Bandwidth Monitoring Event Configuration */
311311

312+
#define X86_FEATURE_SRSO (11*32+24) /* "" AMD BTB untrain RETs */
313+
#define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */
314+
#define X86_FEATURE_IBPB_ON_VMEXIT (11*32+26) /* "" Issue an IBPB only on VMEXIT */
315+
312316
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
313317
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
314318
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
@@ -442,6 +446,10 @@
442446
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* "" Automatic IBRS */
443447
#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* "" SMM_CTL MSR is not present */
444448

449+
#define X86_FEATURE_SBPB (20*32+27) /* "" Selective Branch Prediction Barrier */
450+
#define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* "" MSR_PRED_CMD[IBPB] flushes all branch type predictions */
451+
#define X86_FEATURE_SRSO_NO (20*32+29) /* "" CPU is not affected by SRSO */
452+
445453
/*
446454
* BUG word(s)
447455
*/
@@ -484,4 +492,6 @@
484492
#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
485493
#define X86_BUG_SMT_RSB X86_BUG(29) /* CPU is vulnerable to Cross-Thread Return Address Predictions */
486494

495+
/* BUG word 2 */
496+
#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */
487497
#endif /* _ASM_X86_CPUFEATURES_H */

arch/x86/include/asm/msr-index.h

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757

5858
#define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */
5959
#define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */
60+
#define PRED_CMD_SBPB BIT(7) /* Selective Branch Prediction Barrier */
6061

6162
#define MSR_PPIN_CTL 0x0000004e
6263
#define MSR_PPIN 0x0000004f

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

+18-5
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@
211211
* eventually turn into it's own annotation.
212212
*/
213213
.macro VALIDATE_UNRET_END
214-
#if defined(CONFIG_NOINSTR_VALIDATION) && defined(CONFIG_CPU_UNRET_ENTRY)
214+
#if defined(CONFIG_NOINSTR_VALIDATION) && \
215+
(defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO))
215216
ANNOTATE_RETPOLINE_SAFE
216217
nop
217218
#endif
@@ -289,13 +290,18 @@
289290
*/
290291
.macro UNTRAIN_RET
291292
#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY) || \
292-
defined(CONFIG_CALL_DEPTH_TRACKING)
293+
defined(CONFIG_CALL_DEPTH_TRACKING) || defined(CONFIG_CPU_SRSO)
293294
VALIDATE_UNRET_END
294295
ALTERNATIVE_3 "", \
295296
CALL_ZEN_UNTRAIN_RET, X86_FEATURE_UNRET, \
296297
"call entry_ibpb", X86_FEATURE_ENTRY_IBPB, \
297298
__stringify(RESET_CALL_DEPTH), X86_FEATURE_CALL_DEPTH
298299
#endif
300+
301+
#ifdef CONFIG_CPU_SRSO
302+
ALTERNATIVE_2 "", "call srso_untrain_ret", X86_FEATURE_SRSO, \
303+
"call srso_untrain_ret_alias", X86_FEATURE_SRSO_ALIAS
304+
#endif
299305
.endm
300306

301307
.macro UNTRAIN_RET_FROM_CALL
@@ -307,6 +313,11 @@
307313
"call entry_ibpb", X86_FEATURE_ENTRY_IBPB, \
308314
__stringify(RESET_CALL_DEPTH_FROM_CALL), X86_FEATURE_CALL_DEPTH
309315
#endif
316+
317+
#ifdef CONFIG_CPU_SRSO
318+
ALTERNATIVE_2 "", "call srso_untrain_ret", X86_FEATURE_SRSO, \
319+
"call srso_untrain_ret_alias", X86_FEATURE_SRSO_ALIAS
320+
#endif
310321
.endm
311322

312323

@@ -332,6 +343,8 @@ extern retpoline_thunk_t __x86_indirect_jump_thunk_array[];
332343

333344
extern void __x86_return_thunk(void);
334345
extern void zen_untrain_ret(void);
346+
extern void srso_untrain_ret(void);
347+
extern void srso_untrain_ret_alias(void);
335348
extern void entry_ibpb(void);
336349

337350
#ifdef CONFIG_CALL_THUNKS
@@ -479,11 +492,11 @@ void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature)
479492
: "memory");
480493
}
481494

495+
extern u64 x86_pred_cmd;
496+
482497
static inline void indirect_branch_prediction_barrier(void)
483498
{
484-
u64 val = PRED_CMD_IBPB;
485-
486-
alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB);
499+
alternative_msr_write(MSR_IA32_PRED_CMD, x86_pred_cmd, X86_FEATURE_USE_IBPB);
487500
}
488501

489502
/* The Intel SPEC CTRL MSR base value cache */

arch/x86/include/asm/processor.h

+2
Original file line numberDiff line numberDiff line change
@@ -682,9 +682,11 @@ extern u16 get_llc_id(unsigned int cpu);
682682
#ifdef CONFIG_CPU_SUP_AMD
683683
extern u32 amd_get_nodes_per_socket(void);
684684
extern u32 amd_get_highest_perf(void);
685+
extern bool cpu_has_ibpb_brtype_microcode(void);
685686
#else
686687
static inline u32 amd_get_nodes_per_socket(void) { return 0; }
687688
static inline u32 amd_get_highest_perf(void) { return 0; }
689+
static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; }
688690
#endif
689691

690692
extern unsigned long arch_align_stack(unsigned long sp);

arch/x86/kernel/cpu/amd.c

+19
Original file line numberDiff line numberDiff line change
@@ -1290,3 +1290,22 @@ void amd_check_microcode(void)
12901290
{
12911291
on_each_cpu(zenbleed_check_cpu, NULL, 1);
12921292
}
1293+
1294+
bool cpu_has_ibpb_brtype_microcode(void)
1295+
{
1296+
switch (boot_cpu_data.x86) {
1297+
/* Zen1/2 IBPB flushes branch type predictions too. */
1298+
case 0x17:
1299+
return boot_cpu_has(X86_FEATURE_AMD_IBPB);
1300+
case 0x19:
1301+
/* Poke the MSR bit on Zen3/4 to check its presence. */
1302+
if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) {
1303+
setup_force_cpu_cap(X86_FEATURE_SBPB);
1304+
return true;
1305+
} else {
1306+
return false;
1307+
}
1308+
default:
1309+
return false;
1310+
}
1311+
}

0 commit comments

Comments
 (0)