]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
14ef3ca3f36559bff78b8b495dc2a8d0bdbec7c4
[thirdparty/kernel/stable-queue.git] /
1 From foo@baz Tue Mar 8 07:35:31 PM CET 2022
2 From: Josh Poimboeuf <jpoimboe@redhat.com>
3 Date: Fri, 18 Feb 2022 11:49:08 -0800
4 Subject: x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation reporting
5
6 From: Josh Poimboeuf <jpoimboe@redhat.com>
7
8 commit 44a3918c8245ab10c6c9719dd12e7a8d291980d8 upstream.
9
10 With unprivileged eBPF enabled, eIBRS (without retpoline) is vulnerable
11 to Spectre v2 BHB-based attacks.
12
13 When both are enabled, print a warning message and report it in the
14 'spectre_v2' sysfs vulnerabilities file.
15
16 Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
17 Signed-off-by: Borislav Petkov <bp@suse.de>
18 Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
19 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
20 ---
21 arch/x86/kernel/cpu/bugs.c | 35 +++++++++++++++++++++++++++++------
22 include/linux/bpf.h | 12 ++++++++++++
23 kernel/sysctl.c | 7 +++++++
24 3 files changed, 48 insertions(+), 6 deletions(-)
25
26 --- a/arch/x86/kernel/cpu/bugs.c
27 +++ b/arch/x86/kernel/cpu/bugs.c
28 @@ -16,6 +16,7 @@
29 #include <linux/prctl.h>
30 #include <linux/sched/smt.h>
31 #include <linux/pgtable.h>
32 +#include <linux/bpf.h>
33
34 #include <asm/spec-ctrl.h>
35 #include <asm/cmdline.h>
36 @@ -650,6 +651,16 @@ static inline const char *spectre_v2_mod
37 static inline const char *spectre_v2_module_string(void) { return ""; }
38 #endif
39
40 +#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n"
41 +
42 +#ifdef CONFIG_BPF_SYSCALL
43 +void unpriv_ebpf_notify(int new_state)
44 +{
45 + if (spectre_v2_enabled == SPECTRE_V2_EIBRS && !new_state)
46 + pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
47 +}
48 +#endif
49 +
50 static inline bool match_option(const char *arg, int arglen, const char *opt)
51 {
52 int len = strlen(opt);
53 @@ -994,6 +1005,9 @@ static void __init spectre_v2_select_mit
54 break;
55 }
56
57 + if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
58 + pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
59 +
60 if (spectre_v2_in_eibrs_mode(mode)) {
61 /* Force it so VMEXIT will restore correctly */
62 x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
63 @@ -1780,6 +1794,20 @@ static char *ibpb_state(void)
64 return "";
65 }
66
67 +static ssize_t spectre_v2_show_state(char *buf)
68 +{
69 + if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
70 + return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n");
71 +
72 + return sprintf(buf, "%s%s%s%s%s%s\n",
73 + spectre_v2_strings[spectre_v2_enabled],
74 + ibpb_state(),
75 + boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
76 + stibp_state(),
77 + boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
78 + spectre_v2_module_string());
79 +}
80 +
81 static ssize_t srbds_show_state(char *buf)
82 {
83 return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]);
84 @@ -1805,12 +1833,7 @@ static ssize_t cpu_show_common(struct de
85 return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
86
87 case X86_BUG_SPECTRE_V2:
88 - return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
89 - ibpb_state(),
90 - boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
91 - stibp_state(),
92 - boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
93 - spectre_v2_module_string());
94 + return spectre_v2_show_state(buf);
95
96 case X86_BUG_SPEC_STORE_BYPASS:
97 return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);
98 --- a/include/linux/bpf.h
99 +++ b/include/linux/bpf.h
100 @@ -1774,6 +1774,12 @@ bool bpf_prog_has_kfunc_call(const struc
101 const struct btf_func_model *
102 bpf_jit_find_kfunc_model(const struct bpf_prog *prog,
103 const struct bpf_insn *insn);
104 +
105 +static inline bool unprivileged_ebpf_enabled(void)
106 +{
107 + return !sysctl_unprivileged_bpf_disabled;
108 +}
109 +
110 #else /* !CONFIG_BPF_SYSCALL */
111 static inline struct bpf_prog *bpf_prog_get(u32 ufd)
112 {
113 @@ -1993,6 +1999,12 @@ bpf_jit_find_kfunc_model(const struct bp
114 {
115 return NULL;
116 }
117 +
118 +static inline bool unprivileged_ebpf_enabled(void)
119 +{
120 + return false;
121 +}
122 +
123 #endif /* CONFIG_BPF_SYSCALL */
124
125 void __bpf_free_used_btfs(struct bpf_prog_aux *aux,
126 --- a/kernel/sysctl.c
127 +++ b/kernel/sysctl.c
128 @@ -228,6 +228,10 @@ static int bpf_stats_handler(struct ctl_
129 return ret;
130 }
131
132 +void __weak unpriv_ebpf_notify(int new_state)
133 +{
134 +}
135 +
136 static int bpf_unpriv_handler(struct ctl_table *table, int write,
137 void *buffer, size_t *lenp, loff_t *ppos)
138 {
139 @@ -245,6 +249,9 @@ static int bpf_unpriv_handler(struct ctl
140 return -EPERM;
141 *(int *)table->data = unpriv_enable;
142 }
143 +
144 + unpriv_ebpf_notify(unpriv_enable);
145 +
146 return ret;
147 }
148 #endif /* CONFIG_BPF_SYSCALL && CONFIG_SYSCTL */