Skip to content

Commit 44a3918

Browse files
jpoimboesuryasaimadhu
authored andcommitted
x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation reporting
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 <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]>
1 parent 5ad3eb1 commit 44a3918

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

arch/x86/kernel/cpu/bugs.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/prctl.h>
1717
#include <linux/sched/smt.h>
1818
#include <linux/pgtable.h>
19+
#include <linux/bpf.h>
1920

2021
#include <asm/spec-ctrl.h>
2122
#include <asm/cmdline.h>
@@ -650,6 +651,16 @@ static inline const char *spectre_v2_module_string(void)
650651
static inline const char *spectre_v2_module_string(void) { return ""; }
651652
#endif
652653

654+
#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n"
655+
656+
#ifdef CONFIG_BPF_SYSCALL
657+
void unpriv_ebpf_notify(int new_state)
658+
{
659+
if (spectre_v2_enabled == SPECTRE_V2_EIBRS && !new_state)
660+
pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
661+
}
662+
#endif
663+
653664
static inline bool match_option(const char *arg, int arglen, const char *opt)
654665
{
655666
int len = strlen(opt);
@@ -994,6 +1005,9 @@ static void __init spectre_v2_select_mitigation(void)
9941005
break;
9951006
}
9961007

1008+
if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
1009+
pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
1010+
9971011
if (spectre_v2_in_eibrs_mode(mode)) {
9981012
/* Force it so VMEXIT will restore correctly */
9991013
x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
@@ -1780,6 +1794,20 @@ static char *ibpb_state(void)
17801794
return "";
17811795
}
17821796

1797+
static ssize_t spectre_v2_show_state(char *buf)
1798+
{
1799+
if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
1800+
return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
1801+
1802+
return sprintf(buf, "%s%s%s%s%s%s\n",
1803+
spectre_v2_strings[spectre_v2_enabled],
1804+
ibpb_state(),
1805+
boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
1806+
stibp_state(),
1807+
boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
1808+
spectre_v2_module_string());
1809+
}
1810+
17831811
static ssize_t srbds_show_state(char *buf)
17841812
{
17851813
return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]);
@@ -1805,12 +1833,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
18051833
return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
18061834

18071835
case X86_BUG_SPECTRE_V2:
1808-
return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
1809-
ibpb_state(),
1810-
boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
1811-
stibp_state(),
1812-
boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
1813-
spectre_v2_module_string());
1836+
return spectre_v2_show_state(buf);
18141837

18151838
case X86_BUG_SPEC_STORE_BYPASS:
18161839
return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);

include/linux/bpf.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,11 @@ struct bpf_core_ctx {
17931793
int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo,
17941794
int relo_idx, void *insn);
17951795

1796+
static inline bool unprivileged_ebpf_enabled(void)
1797+
{
1798+
return !sysctl_unprivileged_bpf_disabled;
1799+
}
1800+
17961801
#else /* !CONFIG_BPF_SYSCALL */
17971802
static inline struct bpf_prog *bpf_prog_get(u32 ufd)
17981803
{
@@ -2012,6 +2017,12 @@ bpf_jit_find_kfunc_model(const struct bpf_prog *prog,
20122017
{
20132018
return NULL;
20142019
}
2020+
2021+
static inline bool unprivileged_ebpf_enabled(void)
2022+
{
2023+
return false;
2024+
}
2025+
20152026
#endif /* CONFIG_BPF_SYSCALL */
20162027

20172028
void __bpf_free_used_btfs(struct bpf_prog_aux *aux,

kernel/sysctl.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ static int bpf_stats_handler(struct ctl_table *table, int write,
180180
return ret;
181181
}
182182

183+
void __weak unpriv_ebpf_notify(int new_state)
184+
{
185+
}
186+
183187
static int bpf_unpriv_handler(struct ctl_table *table, int write,
184188
void *buffer, size_t *lenp, loff_t *ppos)
185189
{
@@ -197,6 +201,9 @@ static int bpf_unpriv_handler(struct ctl_table *table, int write,
197201
return -EPERM;
198202
*(int *)table->data = unpriv_enable;
199203
}
204+
205+
unpriv_ebpf_notify(unpriv_enable);
206+
200207
return ret;
201208
}
202209
#endif /* CONFIG_BPF_SYSCALL && CONFIG_SYSCTL */

0 commit comments

Comments
 (0)