]>
Commit | Line | Data |
---|---|---|
6fa88700 GKH |
1 | From 0d11186aeea236b1b25ce25ca7c5ab61cb08801c Mon Sep 17 00:00:00 2001 |
2 | From: Thomas Gleixner <tglx@linutronix.de> | |
3 | Date: Sun, 25 Nov 2018 19:33:55 +0100 | |
4 | Subject: [PATCH 47/76] x86/speculation: Add seccomp Spectre v2 user space | |
5 | protection mode | |
6 | ||
7 | commit 6b3e64c237c072797a9ec918654a60e3a46488e2 upstream. | |
8 | ||
9 | If 'prctl' mode of user space protection from spectre v2 is selected | |
10 | on the kernel command-line, STIBP and IBPB are applied on tasks which | |
11 | restrict their indirect branch speculation via prctl. | |
12 | ||
13 | SECCOMP enables the SSBD mitigation for sandboxed tasks already, so it | |
14 | makes sense to prevent spectre v2 user space to user space attacks as | |
15 | well. | |
16 | ||
17 | The Intel mitigation guide documents how STIPB works: | |
18 | ||
19 | Setting bit 1 (STIBP) of the IA32_SPEC_CTRL MSR on a logical processor | |
20 | prevents the predicted targets of indirect branches on any logical | |
21 | processor of that core from being controlled by software that executes | |
22 | (or executed previously) on another logical processor of the same core. | |
23 | ||
24 | Ergo setting STIBP protects the task itself from being attacked from a task | |
25 | running on a different hyper-thread and protects the tasks running on | |
26 | different hyper-threads from being attacked. | |
27 | ||
28 | While the document suggests that the branch predictors are shielded between | |
29 | the logical processors, the observed performance regressions suggest that | |
30 | STIBP simply disables the branch predictor more or less completely. Of | |
31 | course the document wording is vague, but the fact that there is also no | |
32 | requirement for issuing IBPB when STIBP is used points clearly in that | |
33 | direction. The kernel still issues IBPB even when STIBP is used until Intel | |
34 | clarifies the whole mechanism. | |
35 | ||
36 | IBPB is issued when the task switches out, so malicious sandbox code cannot | |
37 | mistrain the branch predictor for the next user space task on the same | |
38 | logical processor. | |
39 | ||
40 | Signed-off-by: Jiri Kosina <jkosina@suse.cz> | |
41 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | |
42 | Reviewed-by: Ingo Molnar <mingo@kernel.org> | |
43 | Cc: Peter Zijlstra <peterz@infradead.org> | |
44 | Cc: Andy Lutomirski <luto@kernel.org> | |
45 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
46 | Cc: Tom Lendacky <thomas.lendacky@amd.com> | |
47 | Cc: Josh Poimboeuf <jpoimboe@redhat.com> | |
48 | Cc: Andrea Arcangeli <aarcange@redhat.com> | |
49 | Cc: David Woodhouse <dwmw@amazon.co.uk> | |
50 | Cc: Tim Chen <tim.c.chen@linux.intel.com> | |
51 | Cc: Andi Kleen <ak@linux.intel.com> | |
52 | Cc: Dave Hansen <dave.hansen@intel.com> | |
53 | Cc: Casey Schaufler <casey.schaufler@intel.com> | |
54 | Cc: Asit Mallick <asit.k.mallick@intel.com> | |
55 | Cc: Arjan van de Ven <arjan@linux.intel.com> | |
56 | Cc: Jon Masters <jcm@redhat.com> | |
57 | Cc: Waiman Long <longman9394@gmail.com> | |
58 | Cc: Greg KH <gregkh@linuxfoundation.org> | |
59 | Cc: Dave Stewart <david.c.stewart@intel.com> | |
60 | Cc: Kees Cook <keescook@chromium.org> | |
61 | Link: https://lkml.kernel.org/r/20181125185006.051663132@linutronix.de | |
62 | [bwh: Backported to 4.9: adjust filename] | |
63 | Signed-off-by: Ben Hutchings <ben@decadent.org.uk> | |
64 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
65 | --- | |
66 | Documentation/kernel-parameters.txt | 9 ++++++++- | |
67 | arch/x86/include/asm/nospec-branch.h | 1 + | |
68 | arch/x86/kernel/cpu/bugs.c | 17 ++++++++++++++++- | |
69 | 3 files changed, 25 insertions(+), 2 deletions(-) | |
70 | ||
71 | diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt | |
72 | index f87e4bf2ab25..65a6e663f487 100644 | |
73 | --- a/Documentation/kernel-parameters.txt | |
74 | +++ b/Documentation/kernel-parameters.txt | |
75 | @@ -4080,9 +4080,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |
76 | per thread. The mitigation control state | |
77 | is inherited on fork. | |
78 | ||
79 | + seccomp | |
80 | + - Same as "prctl" above, but all seccomp | |
81 | + threads will enable the mitigation unless | |
82 | + they explicitly opt out. | |
83 | + | |
84 | auto - Kernel selects the mitigation depending on | |
85 | the available CPU features and vulnerability. | |
86 | - Default is prctl. | |
87 | + | |
88 | + Default mitigation: | |
89 | + If CONFIG_SECCOMP=y then "seccomp", otherwise "prctl" | |
90 | ||
91 | Not specifying this option is equivalent to | |
92 | spectre_v2_user=auto. | |
93 | diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h | |
94 | index 37ea761495c5..14bf299b369f 100644 | |
95 | --- a/arch/x86/include/asm/nospec-branch.h | |
96 | +++ b/arch/x86/include/asm/nospec-branch.h | |
97 | @@ -224,6 +224,7 @@ enum spectre_v2_user_mitigation { | |
98 | SPECTRE_V2_USER_NONE, | |
99 | SPECTRE_V2_USER_STRICT, | |
100 | SPECTRE_V2_USER_PRCTL, | |
101 | + SPECTRE_V2_USER_SECCOMP, | |
102 | }; | |
103 | ||
104 | /* The Speculative Store Bypass disable variants */ | |
105 | diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c | |
106 | index e28598f3ab12..00263ee4f6a1 100644 | |
107 | --- a/arch/x86/kernel/cpu/bugs.c | |
108 | +++ b/arch/x86/kernel/cpu/bugs.c | |
109 | @@ -254,12 +254,14 @@ enum spectre_v2_user_cmd { | |
110 | SPECTRE_V2_USER_CMD_AUTO, | |
111 | SPECTRE_V2_USER_CMD_FORCE, | |
112 | SPECTRE_V2_USER_CMD_PRCTL, | |
113 | + SPECTRE_V2_USER_CMD_SECCOMP, | |
114 | }; | |
115 | ||
116 | static const char * const spectre_v2_user_strings[] = { | |
117 | [SPECTRE_V2_USER_NONE] = "User space: Vulnerable", | |
118 | [SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection", | |
119 | [SPECTRE_V2_USER_PRCTL] = "User space: Mitigation: STIBP via prctl", | |
120 | + [SPECTRE_V2_USER_SECCOMP] = "User space: Mitigation: STIBP via seccomp and prctl", | |
121 | }; | |
122 | ||
123 | static const struct { | |
124 | @@ -271,6 +273,7 @@ static const struct { | |
125 | { "off", SPECTRE_V2_USER_CMD_NONE, false }, | |
126 | { "on", SPECTRE_V2_USER_CMD_FORCE, true }, | |
127 | { "prctl", SPECTRE_V2_USER_CMD_PRCTL, false }, | |
128 | + { "seccomp", SPECTRE_V2_USER_CMD_SECCOMP, false }, | |
129 | }; | |
130 | ||
131 | static void __init spec_v2_user_print_cond(const char *reason, bool secure) | |
132 | @@ -330,10 +333,16 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) | |
133 | case SPECTRE_V2_USER_CMD_FORCE: | |
134 | mode = SPECTRE_V2_USER_STRICT; | |
135 | break; | |
136 | - case SPECTRE_V2_USER_CMD_AUTO: | |
137 | case SPECTRE_V2_USER_CMD_PRCTL: | |
138 | mode = SPECTRE_V2_USER_PRCTL; | |
139 | break; | |
140 | + case SPECTRE_V2_USER_CMD_AUTO: | |
141 | + case SPECTRE_V2_USER_CMD_SECCOMP: | |
142 | + if (IS_ENABLED(CONFIG_SECCOMP)) | |
143 | + mode = SPECTRE_V2_USER_SECCOMP; | |
144 | + else | |
145 | + mode = SPECTRE_V2_USER_PRCTL; | |
146 | + break; | |
147 | } | |
148 | ||
149 | /* Initialize Indirect Branch Prediction Barrier */ | |
150 | @@ -345,6 +354,7 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) | |
151 | static_branch_enable(&switch_mm_always_ibpb); | |
152 | break; | |
153 | case SPECTRE_V2_USER_PRCTL: | |
154 | + case SPECTRE_V2_USER_SECCOMP: | |
155 | static_branch_enable(&switch_mm_cond_ibpb); | |
156 | break; | |
157 | default: | |
158 | @@ -596,6 +606,7 @@ void arch_smt_update(void) | |
159 | update_stibp_strict(); | |
160 | break; | |
161 | case SPECTRE_V2_USER_PRCTL: | |
162 | + case SPECTRE_V2_USER_SECCOMP: | |
163 | update_indir_branch_cond(); | |
164 | break; | |
165 | } | |
166 | @@ -838,6 +849,8 @@ void arch_seccomp_spec_mitigate(struct task_struct *task) | |
167 | { | |
168 | if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP) | |
169 | ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE); | |
170 | + if (spectre_v2_user == SPECTRE_V2_USER_SECCOMP) | |
171 | + ib_prctl_set(task, PR_SPEC_FORCE_DISABLE); | |
172 | } | |
173 | #endif | |
174 | ||
175 | @@ -869,6 +882,7 @@ static int ib_prctl_get(struct task_struct *task) | |
176 | case SPECTRE_V2_USER_NONE: | |
177 | return PR_SPEC_ENABLE; | |
178 | case SPECTRE_V2_USER_PRCTL: | |
179 | + case SPECTRE_V2_USER_SECCOMP: | |
180 | if (task_spec_ib_force_disable(task)) | |
181 | return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; | |
182 | if (task_spec_ib_disable(task)) | |
183 | @@ -1069,6 +1083,7 @@ static char *stibp_state(void) | |
184 | case SPECTRE_V2_USER_STRICT: | |
185 | return ", STIBP: forced"; | |
186 | case SPECTRE_V2_USER_PRCTL: | |
187 | + case SPECTRE_V2_USER_SECCOMP: | |
188 | if (static_key_enabled(&switch_to_cond_stibp)) | |
189 | return ", STIBP: conditional"; | |
190 | } | |
191 | -- | |
192 | 2.21.0 | |
193 |