]>
Commit | Line | Data |
---|---|---|
ec8f24b7 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
9f671e58 KC |
2 | menu "Kernel hardening options" |
3 | ||
4 | config GCC_PLUGIN_STRUCTLEAK | |
5 | bool | |
6 | help | |
7 | While the kernel is built with warnings enabled for any missed | |
8 | stack variable initializations, this warning is silenced for | |
9 | anything passed by reference to another function, under the | |
10 | occasionally misguided assumption that the function will do | |
11 | the initialization. As this regularly leads to exploitable | |
12 | flaws, this plugin is available to identify and zero-initialize | |
13 | such variables, depending on the chosen level of coverage. | |
14 | ||
15 | This plugin was originally ported from grsecurity/PaX. More | |
16 | information at: | |
17 | * https://grsecurity.net/ | |
18 | * https://pax.grsecurity.net/ | |
19 | ||
20 | menu "Memory initialization" | |
21 | ||
f0fe00d4 | 22 | config CC_HAS_AUTO_VAR_INIT_PATTERN |
709a972e KC |
23 | def_bool $(cc-option,-ftrivial-auto-var-init=pattern) |
24 | ||
607e57c6 KC |
25 | config CC_HAS_AUTO_VAR_INIT_ZERO_BARE |
26 | def_bool $(cc-option,-ftrivial-auto-var-init=zero) | |
27 | ||
28 | config CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER | |
29 | # Clang 16 and later warn about using the -enable flag, but it | |
30 | # is required before then. | |
f0fe00d4 | 31 | def_bool $(cc-option,-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang) |
607e57c6 KC |
32 | depends on !CC_HAS_AUTO_VAR_INIT_ZERO_BARE |
33 | ||
34 | config CC_HAS_AUTO_VAR_INIT_ZERO | |
35 | def_bool CC_HAS_AUTO_VAR_INIT_ZERO_BARE || CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER | |
f0fe00d4 | 36 | |
9f671e58 KC |
37 | choice |
38 | prompt "Initialize kernel stack variables at function entry" | |
39 | default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS | |
f0fe00d4 | 40 | default INIT_STACK_ALL_PATTERN if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT_PATTERN |
f02003c8 | 41 | default INIT_STACK_ALL_ZERO if CC_HAS_AUTO_VAR_INIT_ZERO |
9f671e58 KC |
42 | default INIT_STACK_NONE |
43 | help | |
44 | This option enables initialization of stack variables at | |
45 | function entry time. This has the possibility to have the | |
46 | greatest coverage (since all functions can have their | |
47 | variables initialized), but the performance impact depends | |
48 | on the function calling complexity of a given workload's | |
49 | syscalls. | |
50 | ||
51 | This chooses the level of coverage over classes of potentially | |
dcb7c0b9 | 52 | uninitialized variables. The selected class of variable will be |
9f671e58 KC |
53 | initialized before use in a function. |
54 | ||
55 | config INIT_STACK_NONE | |
dcb7c0b9 | 56 | bool "no automatic stack variable initialization (weakest)" |
9f671e58 KC |
57 | help |
58 | Disable automatic stack variable initialization. | |
59 | This leaves the kernel vulnerable to the standard | |
60 | classes of uninitialized stack variable exploits | |
61 | and information exposures. | |
62 | ||
63 | config GCC_PLUGIN_STRUCTLEAK_USER | |
64 | bool "zero-init structs marked for userspace (weak)" | |
8bd51a2b KC |
65 | # Plugin can be removed once the kernel only supports GCC 12+ |
66 | depends on GCC_PLUGINS && !CC_HAS_AUTO_VAR_INIT_ZERO | |
9f671e58 KC |
67 | select GCC_PLUGIN_STRUCTLEAK |
68 | help | |
69 | Zero-initialize any structures on the stack containing | |
70 | a __user attribute. This can prevent some classes of | |
71 | uninitialized stack variable exploits and information | |
72 | exposures, like CVE-2013-2141: | |
73 | https://git.kernel.org/linus/b9e146d8eb3b9eca | |
74 | ||
75 | config GCC_PLUGIN_STRUCTLEAK_BYREF | |
76 | bool "zero-init structs passed by reference (strong)" | |
8bd51a2b KC |
77 | # Plugin can be removed once the kernel only supports GCC 12+ |
78 | depends on GCC_PLUGINS && !CC_HAS_AUTO_VAR_INIT_ZERO | |
02c58773 | 79 | depends on !(KASAN && KASAN_STACK) |
9f671e58 KC |
80 | select GCC_PLUGIN_STRUCTLEAK |
81 | help | |
82 | Zero-initialize any structures on the stack that may | |
83 | be passed by reference and had not already been | |
84 | explicitly initialized. This can prevent most classes | |
85 | of uninitialized stack variable exploits and information | |
86 | exposures, like CVE-2017-1000410: | |
87 | https://git.kernel.org/linus/06e7e776ca4d3654 | |
88 | ||
173e6ee2 AB |
89 | As a side-effect, this keeps a lot of variables on the |
90 | stack that can otherwise be optimized out, so combining | |
91 | this with CONFIG_KASAN_STACK can lead to a stack overflow | |
92 | and is disallowed. | |
93 | ||
9f671e58 | 94 | config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL |
dcb7c0b9 | 95 | bool "zero-init everything passed by reference (very strong)" |
8bd51a2b KC |
96 | # Plugin can be removed once the kernel only supports GCC 12+ |
97 | depends on GCC_PLUGINS && !CC_HAS_AUTO_VAR_INIT_ZERO | |
02c58773 | 98 | depends on !(KASAN && KASAN_STACK) |
9f671e58 KC |
99 | select GCC_PLUGIN_STRUCTLEAK |
100 | help | |
101 | Zero-initialize any stack variables that may be passed | |
102 | by reference and had not already been explicitly | |
103 | initialized. This is intended to eliminate all classes | |
104 | of uninitialized stack variable exploits and information | |
105 | exposures. | |
106 | ||
dcb7c0b9 KC |
107 | As a side-effect, this keeps a lot of variables on the |
108 | stack that can otherwise be optimized out, so combining | |
109 | this with CONFIG_KASAN_STACK can lead to a stack overflow | |
110 | and is disallowed. | |
111 | ||
f0fe00d4 | 112 | config INIT_STACK_ALL_PATTERN |
dcb7c0b9 | 113 | bool "pattern-init everything (strongest)" |
f0fe00d4 | 114 | depends on CC_HAS_AUTO_VAR_INIT_PATTERN |
42eaa27d | 115 | depends on !KMSAN |
709a972e | 116 | help |
dcb7c0b9 KC |
117 | Initializes everything on the stack (including padding) |
118 | with a specific debug value. This is intended to eliminate | |
119 | all classes of uninitialized stack variable exploits and | |
120 | information exposures, even variables that were warned about | |
121 | having been left uninitialized. | |
709a972e | 122 | |
f0fe00d4 | 123 | Pattern initialization is known to provoke many existing bugs |
124 | related to uninitialized locals, e.g. pointers receive | |
dcb7c0b9 KC |
125 | non-NULL values, buffer sizes and indices are very big. The |
126 | pattern is situation-specific; Clang on 64-bit uses 0xAA | |
127 | repeating for all types and padding except float and double | |
128 | which use 0xFF repeating (-NaN). Clang on 32-bit uses 0xFF | |
129 | repeating for all types and padding. | |
f0fe00d4 | 130 | |
131 | config INIT_STACK_ALL_ZERO | |
dcb7c0b9 | 132 | bool "zero-init everything (strongest and safest)" |
f0fe00d4 | 133 | depends on CC_HAS_AUTO_VAR_INIT_ZERO |
42eaa27d | 134 | depends on !KMSAN |
f0fe00d4 | 135 | help |
dcb7c0b9 KC |
136 | Initializes everything on the stack (including padding) |
137 | with a zero value. This is intended to eliminate all | |
138 | classes of uninitialized stack variable exploits and | |
139 | information exposures, even variables that were warned | |
140 | about having been left uninitialized. | |
141 | ||
142 | Zero initialization provides safe defaults for strings | |
143 | (immediately NUL-terminated), pointers (NULL), indices | |
144 | (index 0), and sizes (0 length), so it is therefore more | |
145 | suitable as a production security mitigation than pattern | |
146 | initialization. | |
f0fe00d4 | 147 | |
9f671e58 KC |
148 | endchoice |
149 | ||
150 | config GCC_PLUGIN_STRUCTLEAK_VERBOSE | |
151 | bool "Report forcefully initialized variables" | |
152 | depends on GCC_PLUGIN_STRUCTLEAK | |
153 | depends on !COMPILE_TEST # too noisy | |
154 | help | |
155 | This option will cause a warning to be printed each time the | |
156 | structleak plugin finds a variable it thinks needs to be | |
157 | initialized. Since not all existing initializers are detected | |
158 | by the plugin, this can produce false positive warnings. | |
159 | ||
b6a6a377 KC |
160 | config GCC_PLUGIN_STACKLEAK |
161 | bool "Poison kernel stack before returning from syscalls" | |
162 | depends on GCC_PLUGINS | |
163 | depends on HAVE_ARCH_STACKLEAK | |
164 | help | |
165 | This option makes the kernel erase the kernel stack before | |
166 | returning from system calls. This has the effect of leaving | |
167 | the stack initialized to the poison value, which both reduces | |
168 | the lifetime of any sensitive stack contents and reduces | |
169 | potential for uninitialized stack variable exploits or information | |
170 | exposures (it does not cover functions reaching the same stack | |
171 | depth as prior functions during the same syscall). This blocks | |
172 | most uninitialized stack variable attacks, with the performance | |
173 | impact being driven by the depth of the stack usage, rather than | |
174 | the function calling complexity. | |
175 | ||
176 | The performance impact on a single CPU system kernel compilation | |
177 | sees a 1% slowdown, other systems and workloads may vary and you | |
178 | are advised to test this feature on your expected workload before | |
179 | deploying it. | |
180 | ||
181 | This plugin was ported from grsecurity/PaX. More information at: | |
182 | * https://grsecurity.net/ | |
183 | * https://pax.grsecurity.net/ | |
184 | ||
f154066b KC |
185 | config GCC_PLUGIN_STACKLEAK_VERBOSE |
186 | bool "Report stack depth analysis instrumentation" if EXPERT | |
187 | depends on GCC_PLUGIN_STACKLEAK | |
188 | depends on !COMPILE_TEST # too noisy | |
189 | help | |
190 | This option will cause a warning to be printed each time the | |
191 | stackleak plugin finds a function it thinks needs to be | |
192 | instrumented. This is useful for comparing coverage between | |
193 | builds. | |
194 | ||
b6a6a377 KC |
195 | config STACKLEAK_TRACK_MIN_SIZE |
196 | int "Minimum stack frame size of functions tracked by STACKLEAK" | |
197 | default 100 | |
198 | range 0 4096 | |
199 | depends on GCC_PLUGIN_STACKLEAK | |
200 | help | |
201 | The STACKLEAK gcc plugin instruments the kernel code for tracking | |
202 | the lowest border of the kernel stack (and for some other purposes). | |
203 | It inserts the stackleak_track_stack() call for the functions with | |
204 | a stack frame size greater than or equal to this parameter. | |
205 | If unsure, leave the default value 100. | |
206 | ||
207 | config STACKLEAK_METRICS | |
208 | bool "Show STACKLEAK metrics in the /proc file system" | |
209 | depends on GCC_PLUGIN_STACKLEAK | |
210 | depends on PROC_FS | |
211 | help | |
212 | If this is set, STACKLEAK metrics for every task are available in | |
213 | the /proc file system. In particular, /proc/<pid>/stack_depth | |
214 | shows the maximum kernel stack consumption for the current and | |
215 | previous syscalls. Although this information is not precise, it | |
216 | can be useful for estimating the STACKLEAK performance impact for | |
217 | your workloads. | |
218 | ||
219 | config STACKLEAK_RUNTIME_DISABLE | |
220 | bool "Allow runtime disabling of kernel stack erasing" | |
221 | depends on GCC_PLUGIN_STACKLEAK | |
222 | help | |
223 | This option provides 'stack_erasing' sysctl, which can be used in | |
224 | runtime to control kernel stack erasing for kernels built with | |
225 | CONFIG_GCC_PLUGIN_STACKLEAK. | |
226 | ||
6471384a AP |
227 | config INIT_ON_ALLOC_DEFAULT_ON |
228 | bool "Enable heap memory zeroing on allocation by default" | |
42eaa27d | 229 | depends on !KMSAN |
6471384a AP |
230 | help |
231 | This has the effect of setting "init_on_alloc=1" on the kernel | |
232 | command line. This can be disabled with "init_on_alloc=0". | |
233 | When "init_on_alloc" is enabled, all page allocator and slab | |
234 | allocator memory will be zeroed when allocated, eliminating | |
235 | many kinds of "uninitialized heap memory" flaws, especially | |
236 | heap content exposures. The performance impact varies by | |
237 | workload, but most cases see <1% impact. Some synthetic | |
238 | workloads have measured as high as 7%. | |
239 | ||
240 | config INIT_ON_FREE_DEFAULT_ON | |
241 | bool "Enable heap memory zeroing on free by default" | |
42eaa27d | 242 | depends on !KMSAN |
6471384a AP |
243 | help |
244 | This has the effect of setting "init_on_free=1" on the kernel | |
245 | command line. This can be disabled with "init_on_free=0". | |
246 | Similar to "init_on_alloc", when "init_on_free" is enabled, | |
247 | all page allocator and slab allocator memory will be zeroed | |
248 | when freed, eliminating many kinds of "uninitialized heap memory" | |
249 | flaws, especially heap content exposures. The primary difference | |
250 | with "init_on_free" is that data lifetime in memory is reduced, | |
251 | as anything freed is wiped immediately, making live forensics or | |
252 | cold boot memory attacks unable to recover freed memory contents. | |
253 | The performance impact varies by workload, but is more expensive | |
254 | than "init_on_alloc" due to the negative cache effects of | |
255 | touching "cold" memory areas. Most cases see 3-5% impact. Some | |
256 | synthetic workloads have measured as high as 8%. | |
257 | ||
a82adfd5 KC |
258 | config CC_HAS_ZERO_CALL_USED_REGS |
259 | def_bool $(cc-option,-fzero-call-used-regs=used-gpr) | |
d6a9fb87 NC |
260 | # https://github.com/ClangBuiltLinux/linux/issues/1766 |
261 | # https://github.com/llvm/llvm-project/issues/59242 | |
262 | depends on !CC_IS_CLANG || CLANG_VERSION > 150006 | |
a82adfd5 KC |
263 | |
264 | config ZERO_CALL_USED_REGS | |
265 | bool "Enable register zeroing on function exit" | |
266 | depends on CC_HAS_ZERO_CALL_USED_REGS | |
267 | help | |
268 | At the end of functions, always zero any caller-used register | |
269 | contents. This helps ensure that temporary values are not | |
270 | leaked beyond the function boundary. This means that register | |
271 | contents are less likely to be available for side channels | |
272 | and information exposures. Additionally, this helps reduce the | |
273 | number of useful ROP gadgets by about 20% (and removes compiler | |
274 | generated "write-what-where" gadgets) in the resulting kernel | |
275 | image. This has a less than 1% performance impact on most | |
276 | workloads. Image size growth depends on architecture, and should | |
277 | be evaluated for suitability. For example, x86_64 grows by less | |
278 | than 1%, and arm64 grows by about 5%. | |
279 | ||
9f671e58 KC |
280 | endmenu |
281 | ||
aebc7b0d ME |
282 | menu "Hardening of kernel data structures" |
283 | ||
284 | config LIST_HARDENED | |
285 | bool "Check integrity of linked list manipulation" | |
286 | help | |
287 | Minimal integrity checking in the linked-list manipulation routines | |
288 | to catch memory corruptions that are not guaranteed to result in an | |
289 | immediate access fault. | |
290 | ||
291 | If unsure, say N. | |
292 | ||
aa9f10d5 ME |
293 | config BUG_ON_DATA_CORRUPTION |
294 | bool "Trigger a BUG when data corruption is detected" | |
295 | select LIST_HARDENED | |
296 | help | |
297 | Select this option if the kernel should BUG when it encounters | |
298 | data corruption in kernel memory structures when they get checked | |
299 | for validity. | |
300 | ||
301 | If unsure, say N. | |
302 | ||
aebc7b0d ME |
303 | endmenu |
304 | ||
035f7f87 KC |
305 | config CC_HAS_RANDSTRUCT |
306 | def_bool $(cc-option,-frandomize-layout-seed-file=/dev/null) | |
78f7a3fd EB |
307 | # Randstruct was first added in Clang 15, but it isn't safe to use until |
308 | # Clang 16 due to https://github.com/llvm/llvm-project/issues/60349 | |
309 | depends on !CC_IS_CLANG || CLANG_VERSION >= 160000 | |
035f7f87 | 310 | |
595b893e KC |
311 | choice |
312 | prompt "Randomize layout of sensitive kernel structures" | |
035f7f87 | 313 | default RANDSTRUCT_FULL if COMPILE_TEST && (GCC_PLUGINS || CC_HAS_RANDSTRUCT) |
595b893e KC |
314 | default RANDSTRUCT_NONE |
315 | help | |
316 | If you enable this, the layouts of structures that are entirely | |
317 | function pointers (and have not been manually annotated with | |
318 | __no_randomize_layout), or structures that have been explicitly | |
319 | marked with __randomize_layout, will be randomized at compile-time. | |
320 | This can introduce the requirement of an additional information | |
321 | exposure vulnerability for exploits targeting these structure | |
322 | types. | |
323 | ||
324 | Enabling this feature will introduce some performance impact, | |
325 | slightly increase memory usage, and prevent the use of forensic | |
326 | tools like Volatility against the system (unless the kernel | |
327 | source tree isn't cleaned after kernel installation). | |
328 | ||
be2b34fa KC |
329 | The seed used for compilation is in scripts/basic/randomize.seed. |
330 | It remains after a "make clean" to allow for external modules to | |
331 | be compiled with the existing seed and will be removed by a | |
332 | "make mrproper" or "make distclean". This file should not be made | |
333 | public, or the structure layout can be determined. | |
595b893e KC |
334 | |
335 | config RANDSTRUCT_NONE | |
336 | bool "Disable structure layout randomization" | |
337 | help | |
338 | Build normally: no structure layout randomization. | |
339 | ||
340 | config RANDSTRUCT_FULL | |
341 | bool "Fully randomize structure layout" | |
035f7f87 | 342 | depends on CC_HAS_RANDSTRUCT || GCC_PLUGINS |
595b893e KC |
343 | select MODVERSIONS if MODULES |
344 | help | |
345 | Fully randomize the member layout of sensitive | |
346 | structures as much as possible, which may have both a | |
347 | memory size and performance impact. | |
348 | ||
035f7f87 KC |
349 | One difference between the Clang and GCC plugin |
350 | implementations is the handling of bitfields. The GCC | |
351 | plugin treats them as fully separate variables, | |
352 | introducing sometimes significant padding. Clang tries | |
353 | to keep adjacent bitfields together, but with their bit | |
354 | ordering randomized. | |
355 | ||
595b893e KC |
356 | config RANDSTRUCT_PERFORMANCE |
357 | bool "Limit randomization of structure layout to cache-lines" | |
358 | depends on GCC_PLUGINS | |
359 | select MODVERSIONS if MODULES | |
360 | help | |
361 | Randomization of sensitive kernel structures will make a | |
362 | best effort at restricting randomization to cacheline-sized | |
363 | groups of members. It will further not randomize bitfields | |
364 | in structures. This reduces the performance hit of RANDSTRUCT | |
365 | at the cost of weakened randomization. | |
366 | endchoice | |
367 | ||
368 | config RANDSTRUCT | |
369 | def_bool !RANDSTRUCT_NONE | |
370 | ||
371 | config GCC_PLUGIN_RANDSTRUCT | |
372 | def_bool GCC_PLUGINS && RANDSTRUCT | |
373 | help | |
374 | Use GCC plugin to randomize structure layout. | |
375 | ||
376 | This plugin was ported from grsecurity/PaX. More | |
377 | information at: | |
378 | * https://grsecurity.net/ | |
379 | * https://pax.grsecurity.net/ | |
380 | ||
9f671e58 | 381 | endmenu |