Borislav Petkov 0161c6
From: Josh Poimboeuf <jpoimboe@redhat.com>
Borislav Petkov 0161c6
Date: Fri, 25 Feb 2022 14:32:28 -0800
Borislav Petkov 0161c6
Subject: x86/speculation: Warn about eIBRS + LFENCE + Unprivileged eBPF + SMT
Borislav Petkov 0161c6
Git-commit: 0de05d056afdb00eca8c7bbb0c79a3438daf700c
Borislav Petkov 0161c6
Patch-mainline: v5.17 or v5.17-rc8 (next release)
Borislav Petkov 0161c6
References: bsc#1191580 CVE-2022-0001 CVE-2022-0002
Borislav Petkov 0161c6
Borislav Petkov 0161c6
The commit
Borislav Petkov 0161c6
Borislav Petkov 0161c6
   44a3918c8245 ("x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation reporting")
Borislav Petkov 0161c6
Borislav Petkov 0161c6
added a warning for the "eIBRS + unprivileged eBPF" combination, which
Borislav Petkov 0161c6
has been shown to be vulnerable against Spectre v2 BHB-based attacks.
Borislav Petkov 0161c6
Borislav Petkov 0161c6
However, there's no warning about the "eIBRS + LFENCE retpoline +
Borislav Petkov 0161c6
unprivileged eBPF" combo. The LFENCE adds more protection by shortening
Borislav Petkov 0161c6
the speculation window after a mispredicted branch. That makes an attack
Borislav Petkov 0161c6
significantly more difficult, even with unprivileged eBPF. So at least
Borislav Petkov 0161c6
for now the logic doesn't warn about that combination.
Borislav Petkov 0161c6
Borislav Petkov 0161c6
But if you then add SMT into the mix, the SMT attack angle weakens the
Borislav Petkov 0161c6
effectiveness of the LFENCE considerably.
Borislav Petkov 0161c6
Borislav Petkov 0161c6
So extend the "eIBRS + unprivileged eBPF" warning to also include the
Borislav Petkov 0161c6
"eIBRS + LFENCE + unprivileged eBPF + SMT" case.
Borislav Petkov 0161c6
Borislav Petkov 0161c6
  [ bp: Massage commit message. ]
Borislav Petkov 0161c6
Borislav Petkov 0161c6
Suggested-by: Alyssa Milburn <alyssa.milburn@linux.intel.com>
Borislav Petkov 0161c6
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Borislav Petkov 0161c6
Signed-off-by: Borislav Petkov <bp@suse.de>
Borislav Petkov 0161c6
---
Borislav Petkov 0161c6
 arch/x86/kernel/cpu/bugs.c | 27 +++++++++++++++++++++++++--
Borislav Petkov 0161c6
 1 file changed, 25 insertions(+), 2 deletions(-)
Borislav Petkov 0161c6
Borislav Petkov 0161c6
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
Borislav Petkov 0161c6
index cfd116423908..6296e1ebed1d 100644
Borislav Petkov 0161c6
--- a/arch/x86/kernel/cpu/bugs.c
Borislav Petkov 0161c6
+++ b/arch/x86/kernel/cpu/bugs.c
Borislav Petkov 0161c6
@@ -653,12 +653,27 @@ static inline const char *spectre_v2_module_string(void) { return ""; }
Borislav Petkov 0161c6
 
Borislav Petkov 0161c6
 #define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n"
Borislav Petkov 0161c6
 #define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n"
Borislav Petkov 0161c6
+#define SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS+LFENCE mitigation and SMT, data leaks possible via Spectre v2 BHB attacks!\n"
Borislav Petkov 0161c6
 
Borislav Petkov 0161c6
 #ifdef CONFIG_BPF_SYSCALL
Borislav Petkov 0161c6
 void unpriv_ebpf_notify(int new_state)
Borislav Petkov 0161c6
 {
Borislav Petkov 0161c6
-	if (spectre_v2_enabled == SPECTRE_V2_EIBRS && !new_state)
Borislav Petkov 0161c6
+	if (new_state)
Borislav Petkov 0161c6
+		return;
Borislav Petkov 0161c6
+
Borislav Petkov 0161c6
+	/* Unprivileged eBPF is enabled */
Borislav Petkov 0161c6
+
Borislav Petkov 0161c6
+	switch (spectre_v2_enabled) {
Borislav Petkov 0161c6
+	case SPECTRE_V2_EIBRS:
Borislav Petkov 0161c6
 		pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
Borislav Petkov 0161c6
+		break;
Borislav Petkov 0161c6
+	case SPECTRE_V2_EIBRS_LFENCE:
Borislav Petkov 0161c6
+		if (sched_smt_active())
Borislav Petkov 0161c6
+			pr_err(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG);
Borislav Petkov 0161c6
+		break;
Borislav Petkov 0161c6
+	default:
Borislav Petkov 0161c6
+		break;
Borislav Petkov 0161c6
+	}
Borislav Petkov 0161c6
 }
Borislav Petkov 0161c6
 #endif
Borislav Petkov 0161c6
 
Borislav Petkov 0161c6
@@ -1118,6 +1133,10 @@ void cpu_bugs_smt_update(void)
Borislav Petkov 0161c6
 {
Borislav Petkov 0161c6
 	mutex_lock(&spec_ctrl_mutex);
Borislav Petkov 0161c6
 
Borislav Petkov 0161c6
+	if (sched_smt_active() && unprivileged_ebpf_enabled() &&
Borislav Petkov 0161c6
+	    spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
Borislav Petkov 0161c6
+		pr_warn_once(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG);
Borislav Petkov 0161c6
+
Borislav Petkov 0161c6
 	switch (spectre_v2_user_stibp) {
Borislav Petkov 0161c6
 	case SPECTRE_V2_USER_NONE:
Borislav Petkov 0161c6
 		break;
Borislav Petkov 0161c6
@@ -1793,7 +1812,11 @@ static ssize_t spectre_v2_show_state(char *buf)
Borislav Petkov 0161c6
 		return sprintf(buf, "Vulnerable: LFENCE\n");
Borislav Petkov 0161c6
 
Borislav Petkov 0161c6
 	if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
Borislav Petkov 0161c6
-		return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
Borislav Petkov 0161c6
+		return sprintf(buf, "Vulnerable: eIBRS with unprivileged eBPF\n");
Borislav Petkov 0161c6
+
Borislav Petkov 0161c6
+	if (sched_smt_active() && unprivileged_ebpf_enabled() &&
Borislav Petkov 0161c6
+	    spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
Borislav Petkov 0161c6
+		return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
Borislav Petkov 0161c6
 
Borislav Petkov 0161c6
 	return sprintf(buf, "%s%s%s%s%s%s\n",
Borislav Petkov 0161c6
 		       spectre_v2_strings[spectre_v2_enabled],
Borislav Petkov 0161c6