Skip to content

Commit 8e3c543

Browse files
committed
x86/bhi: Add BHI mitigation knob
jira LE-2015 cve CVE-2024-2201 Rebuild_History Non-Buildable kernel-5.14.0-427.42.1.el9_4 commit-author Pawan Gupta <pawan.kumar.gupta@linux.intel.com> commit ec9404e Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-5.14.0-427.42.1.el9_4/ec9404e4.failed Branch history clearing software sequences and hardware control BHI_DIS_S were defined to mitigate Branch History Injection (BHI). Add cmdline spectre_bhi={on|off|auto} to control BHI mitigation: auto - Deploy the hardware mitigation BHI_DIS_S, if available. on - Deploy the hardware mitigation BHI_DIS_S, if available, otherwise deploy the software sequence at syscall entry and VMexit. off - Turn off BHI mitigation. The default is auto mode which does not deploy the software sequence mitigation. This is because of the hardening done in the syscall dispatch path, which is the likely target of BHI. Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com> Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org> (cherry picked from commit ec9404e) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # Documentation/admin-guide/kernel-parameters.txt # arch/x86/include/asm/cpufeatures.h
1 parent edcba5b commit 8e3c543

File tree

1 file changed

+325
-0
lines changed

1 file changed

+325
-0
lines changed
Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
x86/bhi: Add BHI mitigation knob
2+
3+
jira LE-2015
4+
cve CVE-2024-2201
5+
Rebuild_History Non-Buildable kernel-5.14.0-427.42.1.el9_4
6+
commit-author Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
7+
commit ec9404e40e8f36421a2b66ecb76dc2209fe7f3ef
8+
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
9+
Will be included in final tarball splat. Ref for failed cherry-pick at:
10+
ciq/ciq_backports/kernel-5.14.0-427.42.1.el9_4/ec9404e4.failed
11+
12+
Branch history clearing software sequences and hardware control
13+
BHI_DIS_S were defined to mitigate Branch History Injection (BHI).
14+
15+
Add cmdline spectre_bhi={on|off|auto} to control BHI mitigation:
16+
17+
auto - Deploy the hardware mitigation BHI_DIS_S, if available.
18+
on - Deploy the hardware mitigation BHI_DIS_S, if available,
19+
otherwise deploy the software sequence at syscall entry and
20+
VMexit.
21+
off - Turn off BHI mitigation.
22+
23+
The default is auto mode which does not deploy the software sequence
24+
mitigation. This is because of the hardening done in the syscall
25+
dispatch path, which is the likely target of BHI.
26+
27+
Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
28+
Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com>
29+
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
30+
Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com>
31+
Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org>
32+
33+
(cherry picked from commit ec9404e40e8f36421a2b66ecb76dc2209fe7f3ef)
34+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
35+
36+
# Conflicts:
37+
# Documentation/admin-guide/kernel-parameters.txt
38+
# arch/x86/include/asm/cpufeatures.h
39+
diff --cc Documentation/admin-guide/kernel-parameters.txt
40+
index f74f25f00a14,2dbe60c1db22..000000000000
41+
--- a/Documentation/admin-guide/kernel-parameters.txt
42+
+++ b/Documentation/admin-guide/kernel-parameters.txt
43+
@@@ -5722,7 -6063,18 +5722,22 @@@
44+
sonypi.*= [HW] Sony Programmable I/O Control Device driver
45+
See Documentation/admin-guide/laptops/sonypi.rst
46+
47+
++<<<<<<< HEAD
48+
+ spectre_v2= [X86] Control mitigation of Spectre variant 2
49+
++=======
50+
+ spectre_bhi= [X86] Control mitigation of Branch History Injection
51+
+ (BHI) vulnerability. Syscalls are hardened against BHI
52+
+ reglardless of this setting. This setting affects the
53+
+ deployment of the HW BHI control and the SW BHB
54+
+ clearing sequence.
55+
+
56+
+ on - unconditionally enable.
57+
+ off - unconditionally disable.
58+
+ auto - (default) enable only if hardware mitigation
59+
+ control(BHI_DIS_S) is available.
60+
+
61+
+ spectre_v2= [X86,EARLY] Control mitigation of Spectre variant 2
62+
++>>>>>>> ec9404e40e8f (x86/bhi: Add BHI mitigation knob)
63+
(indirect branch speculation) vulnerability.
64+
The default operation protects the kernel from
65+
user space attacks.
66+
diff --cc arch/x86/include/asm/cpufeatures.h
67+
index 54d64f0e0199,a2ee9a00e4a7..000000000000
68+
--- a/arch/x86/include/asm/cpufeatures.h
69+
+++ b/arch/x86/include/asm/cpufeatures.h
70+
@@@ -462,6 -466,9 +462,12 @@@
71+
* Reuse free bits when adding new feature flags!
72+
*/
73+
#define X86_FEATURE_AMD_LBR_PMC_FREEZE (21*32+ 0) /* AMD LBR and PMC Freeze */
74+
++<<<<<<< HEAD
75+
++=======
76+
+ #define X86_FEATURE_CLEAR_BHB_LOOP (21*32+ 1) /* "" Clear branch history at syscall entry using SW loop */
77+
+ #define X86_FEATURE_BHI_CTRL (21*32+ 2) /* "" BHI_DIS_S HW control available */
78+
+ #define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* "" BHI_DIS_S HW control enabled */
79+
++>>>>>>> ec9404e40e8f (x86/bhi: Add BHI mitigation knob)
80+
81+
/*
82+
* BUG word(s)
83+
diff --git a/Documentation/admin-guide/hw-vuln/spectre.rst b/Documentation/admin-guide/hw-vuln/spectre.rst
84+
index 166facdabe9f..07931fc13d60 100644
85+
--- a/Documentation/admin-guide/hw-vuln/spectre.rst
86+
+++ b/Documentation/admin-guide/hw-vuln/spectre.rst
87+
@@ -138,11 +138,10 @@ associated with the source address of the indirect branch. Specifically,
88+
the BHB might be shared across privilege levels even in the presence of
89+
Enhanced IBRS.
90+
91+
-Currently the only known real-world BHB attack vector is via
92+
-unprivileged eBPF. Therefore, it's highly recommended to not enable
93+
-unprivileged eBPF, especially when eIBRS is used (without retpolines).
94+
-For a full mitigation against BHB attacks, it's recommended to use
95+
-retpolines (or eIBRS combined with retpolines).
96+
+Previously the only known real-world BHB attack vector was via unprivileged
97+
+eBPF. Further research has found attacks that don't require unprivileged eBPF.
98+
+For a full mitigation against BHB attacks it is recommended to set BHI_DIS_S or
99+
+use the BHB clearing sequence.
100+
101+
Attack scenarios
102+
----------------
103+
@@ -430,6 +429,21 @@ The possible values in this file are:
104+
'PBRSB-eIBRS: Not affected' CPU is not affected by PBRSB
105+
=========================== =======================================================
106+
107+
+ - Branch History Injection (BHI) protection status:
108+
+
109+
+.. list-table::
110+
+
111+
+ * - BHI: Not affected
112+
+ - System is not affected
113+
+ * - BHI: Retpoline
114+
+ - System is protected by retpoline
115+
+ * - BHI: BHI_DIS_S
116+
+ - System is protected by BHI_DIS_S
117+
+ * - BHI: SW loop
118+
+ - System is protected by software clearing sequence
119+
+ * - BHI: Syscall hardening
120+
+ - Syscalls are hardened against BHI
121+
+
122+
Full mitigation might require a microcode update from the CPU
123+
vendor. When the necessary microcode is not available, the kernel will
124+
report vulnerability.
125+
@@ -484,7 +498,11 @@ Spectre variant 2
126+
127+
Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at
128+
boot, by setting the IBRS bit, and they're automatically protected against
129+
- Spectre v2 variant attacks.
130+
+ some Spectre v2 variant attacks. The BHB can still influence the choice of
131+
+ indirect branch predictor entry, and although branch predictor entries are
132+
+ isolated between modes when eIBRS is enabled, the BHB itself is not isolated
133+
+ between modes. Systems which support BHI_DIS_S will set it to protect against
134+
+ BHI attacks.
135+
136+
On Intel's enhanced IBRS systems, this includes cross-thread branch target
137+
injections on SMT systems (STIBP). In other words, Intel eIBRS enables
138+
@@ -638,6 +656,21 @@ kernel command line.
139+
spectre_v2=off. Spectre variant 1 mitigations
140+
cannot be disabled.
141+
142+
+ spectre_bhi=
143+
+
144+
+ [X86] Control mitigation of Branch History Injection
145+
+ (BHI) vulnerability. Syscalls are hardened against BHI
146+
+ regardless of this setting. This setting affects the deployment
147+
+ of the HW BHI control and the SW BHB clearing sequence.
148+
+
149+
+ on
150+
+ unconditionally enable.
151+
+ off
152+
+ unconditionally disable.
153+
+ auto
154+
+ enable if hardware mitigation
155+
+ control(BHI_DIS_S) is available.
156+
+
157+
For spectre_v2_user see Documentation/admin-guide/kernel-parameters.txt
158+
159+
Mitigation selection guide
160+
* Unmerged path Documentation/admin-guide/kernel-parameters.txt
161+
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
162+
index 2e3190218496..120e57812c00 100644
163+
--- a/arch/x86/Kconfig
164+
+++ b/arch/x86/Kconfig
165+
@@ -2641,6 +2641,31 @@ config MITIGATION_RFDS
166+
stored in floating point, vector and integer registers.
167+
See also <file:Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst>
168+
169+
+choice
170+
+ prompt "Clear branch history"
171+
+ depends on CPU_SUP_INTEL
172+
+ default SPECTRE_BHI_AUTO
173+
+ help
174+
+ Enable BHI mitigations. BHI attacks are a form of Spectre V2 attacks
175+
+ where the branch history buffer is poisoned to speculatively steer
176+
+ indirect branches.
177+
+ See <file:Documentation/admin-guide/hw-vuln/spectre.rst>
178+
+
179+
+config SPECTRE_BHI_ON
180+
+ bool "on"
181+
+ help
182+
+ Equivalent to setting spectre_bhi=on command line parameter.
183+
+config SPECTRE_BHI_OFF
184+
+ bool "off"
185+
+ help
186+
+ Equivalent to setting spectre_bhi=off command line parameter.
187+
+config SPECTRE_BHI_AUTO
188+
+ bool "auto"
189+
+ help
190+
+ Equivalent to setting spectre_bhi=auto command line parameter.
191+
+
192+
+endchoice
193+
+
194+
endif
195+
196+
config ARCH_HAS_ADD_PAGES
197+
* Unmerged path arch/x86/include/asm/cpufeatures.h
198+
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
199+
index d1c0c8f6898b..d65ffa0e7bd2 100644
200+
--- a/arch/x86/kernel/cpu/bugs.c
201+
+++ b/arch/x86/kernel/cpu/bugs.c
202+
@@ -1612,6 +1612,74 @@ static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_
203+
dump_stack();
204+
}
205+
206+
+/*
207+
+ * Set BHI_DIS_S to prevent indirect branches in kernel to be influenced by
208+
+ * branch history in userspace. Not needed if BHI_NO is set.
209+
+ */
210+
+static bool __init spec_ctrl_bhi_dis(void)
211+
+{
212+
+ if (!boot_cpu_has(X86_FEATURE_BHI_CTRL))
213+
+ return false;
214+
+
215+
+ x86_spec_ctrl_base |= SPEC_CTRL_BHI_DIS_S;
216+
+ update_spec_ctrl(x86_spec_ctrl_base);
217+
+ setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_HW);
218+
+
219+
+ return true;
220+
+}
221+
+
222+
+enum bhi_mitigations {
223+
+ BHI_MITIGATION_OFF,
224+
+ BHI_MITIGATION_ON,
225+
+ BHI_MITIGATION_AUTO,
226+
+};
227+
+
228+
+static enum bhi_mitigations bhi_mitigation __ro_after_init =
229+
+ IS_ENABLED(CONFIG_SPECTRE_BHI_ON) ? BHI_MITIGATION_ON :
230+
+ IS_ENABLED(CONFIG_SPECTRE_BHI_OFF) ? BHI_MITIGATION_OFF :
231+
+ BHI_MITIGATION_AUTO;
232+
+
233+
+static int __init spectre_bhi_parse_cmdline(char *str)
234+
+{
235+
+ if (!str)
236+
+ return -EINVAL;
237+
+
238+
+ if (!strcmp(str, "off"))
239+
+ bhi_mitigation = BHI_MITIGATION_OFF;
240+
+ else if (!strcmp(str, "on"))
241+
+ bhi_mitigation = BHI_MITIGATION_ON;
242+
+ else if (!strcmp(str, "auto"))
243+
+ bhi_mitigation = BHI_MITIGATION_AUTO;
244+
+ else
245+
+ pr_err("Ignoring unknown spectre_bhi option (%s)", str);
246+
+
247+
+ return 0;
248+
+}
249+
+early_param("spectre_bhi", spectre_bhi_parse_cmdline);
250+
+
251+
+static void __init bhi_select_mitigation(void)
252+
+{
253+
+ if (bhi_mitigation == BHI_MITIGATION_OFF)
254+
+ return;
255+
+
256+
+ /* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */
257+
+ if (cpu_feature_enabled(X86_FEATURE_RETPOLINE) &&
258+
+ !(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA))
259+
+ return;
260+
+
261+
+ if (spec_ctrl_bhi_dis())
262+
+ return;
263+
+
264+
+ if (!IS_ENABLED(CONFIG_X86_64))
265+
+ return;
266+
+
267+
+ if (bhi_mitigation == BHI_MITIGATION_AUTO)
268+
+ return;
269+
+
270+
+ setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP);
271+
+ pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n");
272+
+}
273+
+
274+
static void __init spectre_v2_select_mitigation(void)
275+
{
276+
enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
277+
@@ -1723,6 +1791,9 @@ static void __init spectre_v2_select_mitigation(void)
278+
mode == SPECTRE_V2_RETPOLINE)
279+
spec_ctrl_disable_kernel_rrsba();
280+
281+
+ if (boot_cpu_has(X86_BUG_BHI))
282+
+ bhi_select_mitigation();
283+
+
284+
spectre_v2_enabled = mode;
285+
pr_info("%s\n", spectre_v2_strings[mode]);
286+
287+
@@ -2814,6 +2885,21 @@ static char *pbrsb_eibrs_state(void)
288+
}
289+
}
290+
291+
+static const char * const spectre_bhi_state(void)
292+
+{
293+
+ if (!boot_cpu_has_bug(X86_BUG_BHI))
294+
+ return "; BHI: Not affected";
295+
+ else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW))
296+
+ return "; BHI: BHI_DIS_S";
297+
+ else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
298+
+ return "; BHI: SW loop";
299+
+ else if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
300+
+ !(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA))
301+
+ return "; BHI: Retpoline";
302+
+
303+
+ return "; BHI: Vulnerable (Syscall hardening enabled)";
304+
+}
305+
+
306+
static ssize_t spectre_v2_show_state(char *buf)
307+
{
308+
if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
309+
@@ -2826,13 +2912,15 @@ static ssize_t spectre_v2_show_state(char *buf)
310+
spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
311+
return sysfs_emit(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
312+
313+
- return sysfs_emit(buf, "%s%s%s%s%s%s%s\n",
314+
+ return sysfs_emit(buf, "%s%s%s%s%s%s%s%s\n",
315+
spectre_v2_strings[spectre_v2_enabled],
316+
ibpb_state(),
317+
boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? "; IBRS_FW" : "",
318+
stibp_state(),
319+
boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? "; RSB filling" : "",
320+
pbrsb_eibrs_state(),
321+
+ spectre_bhi_state(),
322+
+ /* this should always be at the end */
323+
spectre_v2_module_string());
324+
}
325+

0 commit comments

Comments
 (0)