[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220309155856.661941717@linuxfoundation.org>
Date: Wed, 9 Mar 2022 16:59:25 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Josh Poimboeuf <jpoimboe@...hat.com>,
Borislav Petkov <bp@...e.de>,
Thomas Gleixner <tglx@...utronix.de>,
Frank van der Linden <fllinden@...zon.com>,
Ben Hutchings <ben@...adent.org.uk>
Subject: [PATCH 4.9 12/24] x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation reporting
From: Josh Poimboeuf <jpoimboe@...hat.com>
commit 44a3918c8245ab10c6c9719dd12e7a8d291980d8 upstream.
With unprivileged eBPF enabled, eIBRS (without retpoline) is vulnerable
to Spectre v2 BHB-based attacks.
When both are enabled, print a warning message and report it in the
'spectre_v2' sysfs vulnerabilities file.
Signed-off-by: Josh Poimboeuf <jpoimboe@...hat.com>
Signed-off-by: Borislav Petkov <bp@...e.de>
Reviewed-by: Thomas Gleixner <tglx@...utronix.de>
[fllinden@...zon.com: backported to 4.19]
Signed-off-by: Frank van der Linden <fllinden@...zon.com>
[bwh: Backported to 4.9: adjust context]
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
arch/x86/kernel/cpu/bugs.c | 35 +++++++++++++++++++++++++++++------
include/linux/bpf.h | 11 +++++++++++
kernel/sysctl.c | 8 ++++++++
3 files changed, 48 insertions(+), 6 deletions(-)
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -30,6 +30,7 @@
#include <asm/cacheflush.h>
#include <asm/intel-family.h>
#include <asm/e820.h>
+#include <linux/bpf.h>
#include "cpu.h"
@@ -606,6 +607,16 @@ static inline const char *spectre_v2_mod
static inline const char *spectre_v2_module_string(void) { return ""; }
#endif
+#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n"
+
+#ifdef CONFIG_BPF_SYSCALL
+void unpriv_ebpf_notify(int new_state)
+{
+ if (spectre_v2_enabled == SPECTRE_V2_EIBRS && !new_state)
+ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
+}
+#endif
+
static inline bool match_option(const char *arg, int arglen, const char *opt)
{
int len = strlen(opt);
@@ -949,6 +960,9 @@ static void __init spectre_v2_select_mit
break;
}
+ if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
+ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
+
if (spectre_v2_in_eibrs_mode(mode)) {
/* Force it so VMEXIT will restore correctly */
x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
@@ -1686,6 +1700,20 @@ static char *ibpb_state(void)
return "";
}
+static ssize_t spectre_v2_show_state(char *buf)
+{
+ if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
+ return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
+
+ return sprintf(buf, "%s%s%s%s%s%s\n",
+ spectre_v2_strings[spectre_v2_enabled],
+ ibpb_state(),
+ boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
+ stibp_state(),
+ boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
+ spectre_v2_module_string());
+}
+
static ssize_t srbds_show_state(char *buf)
{
return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]);
@@ -1708,12 +1736,7 @@ static ssize_t cpu_show_common(struct de
return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
case X86_BUG_SPECTRE_V2:
- return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
- ibpb_state(),
- boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
- stibp_state(),
- boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
- spectre_v2_module_string());
+ return spectre_v2_show_state(buf);
case X86_BUG_SPEC_STORE_BYPASS:
return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -295,6 +295,11 @@ static inline void bpf_long_memcpy(void
/* verify correctness of eBPF program */
int bpf_check(struct bpf_prog **fp, union bpf_attr *attr);
+
+static inline bool unprivileged_ebpf_enabled(void)
+{
+ return !sysctl_unprivileged_bpf_disabled;
+}
#else
static inline void bpf_register_prog_type(struct bpf_prog_type_list *tl)
{
@@ -322,6 +327,12 @@ static inline struct bpf_prog *bpf_prog_
{
return ERR_PTR(-EOPNOTSUPP);
}
+
+static inline bool unprivileged_ebpf_enabled(void)
+{
+ return false;
+}
+
#endif /* CONFIG_BPF_SYSCALL */
/* verifier prototypes for helper functions called from eBPF programs */
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -222,6 +222,11 @@ static int sysrq_sysctl_handler(struct c
#endif
#ifdef CONFIG_BPF_SYSCALL
+
+void __weak unpriv_ebpf_notify(int new_state)
+{
+}
+
static int bpf_unpriv_handler(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
@@ -239,6 +244,9 @@ static int bpf_unpriv_handler(struct ctl
return -EPERM;
*(int *)table->data = unpriv_enable;
}
+
+ unpriv_ebpf_notify(unpriv_enable);
+
return ret;
}
#endif
Powered by blists - more mailing lists