| # SPDX-License-Identifier: GPL-2.0-only | 
| menu "Kernel hardening options" | 
|   | 
| config GCC_PLUGIN_STRUCTLEAK | 
|     bool | 
|     help | 
|       While the kernel is built with warnings enabled for any missed | 
|       stack variable initializations, this warning is silenced for | 
|       anything passed by reference to another function, under the | 
|       occasionally misguided assumption that the function will do | 
|       the initialization. As this regularly leads to exploitable | 
|       flaws, this plugin is available to identify and zero-initialize | 
|       such variables, depending on the chosen level of coverage. | 
|   | 
|       This plugin was originally ported from grsecurity/PaX. More | 
|       information at: | 
|        * https://grsecurity.net/ | 
|        * https://pax.grsecurity.net/ | 
|   | 
| menu "Memory initialization" | 
|   | 
| config CC_HAS_AUTO_VAR_INIT_PATTERN | 
|     def_bool $(cc-option,-ftrivial-auto-var-init=pattern) | 
|   | 
| config CC_HAS_AUTO_VAR_INIT_ZERO_BARE | 
|     def_bool $(cc-option,-ftrivial-auto-var-init=zero) | 
|   | 
| config CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER | 
|     # Clang 16 and later warn about using the -enable flag, but it | 
|     # is required before then. | 
|     def_bool $(cc-option,-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang) | 
|     depends on !CC_HAS_AUTO_VAR_INIT_ZERO_BARE | 
|   | 
| config CC_HAS_AUTO_VAR_INIT_ZERO | 
|     def_bool CC_HAS_AUTO_VAR_INIT_ZERO_BARE || CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER | 
|   | 
| choice | 
|     prompt "Initialize kernel stack variables at function entry" | 
|     default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS | 
|     default INIT_STACK_ALL_PATTERN if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT_PATTERN | 
|     default INIT_STACK_ALL_ZERO if CC_HAS_AUTO_VAR_INIT_ZERO | 
|     default INIT_STACK_NONE | 
|     help | 
|       This option enables initialization of stack variables at | 
|       function entry time. This has the possibility to have the | 
|       greatest coverage (since all functions can have their | 
|       variables initialized), but the performance impact depends | 
|       on the function calling complexity of a given workload's | 
|       syscalls. | 
|   | 
|       This chooses the level of coverage over classes of potentially | 
|       uninitialized variables. The selected class of variable will be | 
|       initialized before use in a function. | 
|   | 
|     config INIT_STACK_NONE | 
|         bool "no automatic stack variable initialization (weakest)" | 
|         help | 
|           Disable automatic stack variable initialization. | 
|           This leaves the kernel vulnerable to the standard | 
|           classes of uninitialized stack variable exploits | 
|           and information exposures. | 
|   | 
|     config GCC_PLUGIN_STRUCTLEAK_USER | 
|         bool "zero-init structs marked for userspace (weak)" | 
|         depends on GCC_PLUGINS | 
|         select GCC_PLUGIN_STRUCTLEAK | 
|         help | 
|           Zero-initialize any structures on the stack containing | 
|           a __user attribute. This can prevent some classes of | 
|           uninitialized stack variable exploits and information | 
|           exposures, like CVE-2013-2141: | 
|           https://git.kernel.org/linus/b9e146d8eb3b9eca | 
|   | 
|     config GCC_PLUGIN_STRUCTLEAK_BYREF | 
|         bool "zero-init structs passed by reference (strong)" | 
|         depends on GCC_PLUGINS | 
|         depends on !(KASAN && KASAN_STACK) | 
|         select GCC_PLUGIN_STRUCTLEAK | 
|         help | 
|           Zero-initialize any structures on the stack that may | 
|           be passed by reference and had not already been | 
|           explicitly initialized. This can prevent most classes | 
|           of uninitialized stack variable exploits and information | 
|           exposures, like CVE-2017-1000410: | 
|           https://git.kernel.org/linus/06e7e776ca4d3654 | 
|   | 
|           As a side-effect, this keeps a lot of variables on the | 
|           stack that can otherwise be optimized out, so combining | 
|           this with CONFIG_KASAN_STACK can lead to a stack overflow | 
|           and is disallowed. | 
|   | 
|     config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL | 
|         bool "zero-init everything passed by reference (very strong)" | 
|         depends on GCC_PLUGINS | 
|         depends on !(KASAN && KASAN_STACK) | 
|         select GCC_PLUGIN_STRUCTLEAK | 
|         help | 
|           Zero-initialize any stack variables that may be passed | 
|           by reference and had not already been explicitly | 
|           initialized. This is intended to eliminate all classes | 
|           of uninitialized stack variable exploits and information | 
|           exposures. | 
|   | 
|           As a side-effect, this keeps a lot of variables on the | 
|           stack that can otherwise be optimized out, so combining | 
|           this with CONFIG_KASAN_STACK can lead to a stack overflow | 
|           and is disallowed. | 
|   | 
|     config INIT_STACK_ALL_PATTERN | 
|         bool "pattern-init everything (strongest)" | 
|         depends on CC_HAS_AUTO_VAR_INIT_PATTERN | 
|         help | 
|           Initializes everything on the stack (including padding) | 
|           with a specific debug value. This is intended to eliminate | 
|           all classes of uninitialized stack variable exploits and | 
|           information exposures, even variables that were warned about | 
|           having been left uninitialized. | 
|   | 
|           Pattern initialization is known to provoke many existing bugs | 
|           related to uninitialized locals, e.g. pointers receive | 
|           non-NULL values, buffer sizes and indices are very big. The | 
|           pattern is situation-specific; Clang on 64-bit uses 0xAA | 
|           repeating for all types and padding except float and double | 
|           which use 0xFF repeating (-NaN). Clang on 32-bit uses 0xFF | 
|           repeating for all types and padding. | 
|   | 
|     config INIT_STACK_ALL_ZERO | 
|         bool "zero-init everything (strongest and safest)" | 
|         depends on CC_HAS_AUTO_VAR_INIT_ZERO | 
|         help | 
|           Initializes everything on the stack (including padding) | 
|           with a zero value. This is intended to eliminate all | 
|           classes of uninitialized stack variable exploits and | 
|           information exposures, even variables that were warned | 
|           about having been left uninitialized. | 
|   | 
|           Zero initialization provides safe defaults for strings | 
|           (immediately NUL-terminated), pointers (NULL), indices | 
|           (index 0), and sizes (0 length), so it is therefore more | 
|           suitable as a production security mitigation than pattern | 
|           initialization. | 
|   | 
| endchoice | 
|   | 
| config GCC_PLUGIN_STRUCTLEAK_VERBOSE | 
|     bool "Report forcefully initialized variables" | 
|     depends on GCC_PLUGIN_STRUCTLEAK | 
|     depends on !COMPILE_TEST    # too noisy | 
|     help | 
|       This option will cause a warning to be printed each time the | 
|       structleak plugin finds a variable it thinks needs to be | 
|       initialized. Since not all existing initializers are detected | 
|       by the plugin, this can produce false positive warnings. | 
|   | 
| config GCC_PLUGIN_STACKLEAK | 
|     bool "Poison kernel stack before returning from syscalls" | 
|     depends on GCC_PLUGINS | 
|     depends on HAVE_ARCH_STACKLEAK | 
|     help | 
|       This option makes the kernel erase the kernel stack before | 
|       returning from system calls. This has the effect of leaving | 
|       the stack initialized to the poison value, which both reduces | 
|       the lifetime of any sensitive stack contents and reduces | 
|       potential for uninitialized stack variable exploits or information | 
|       exposures (it does not cover functions reaching the same stack | 
|       depth as prior functions during the same syscall). This blocks | 
|       most uninitialized stack variable attacks, with the performance | 
|       impact being driven by the depth of the stack usage, rather than | 
|       the function calling complexity. | 
|   | 
|       The performance impact on a single CPU system kernel compilation | 
|       sees a 1% slowdown, other systems and workloads may vary and you | 
|       are advised to test this feature on your expected workload before | 
|       deploying it. | 
|   | 
|       This plugin was ported from grsecurity/PaX. More information at: | 
|        * https://grsecurity.net/ | 
|        * https://pax.grsecurity.net/ | 
|   | 
| config STACKLEAK_TRACK_MIN_SIZE | 
|     int "Minimum stack frame size of functions tracked by STACKLEAK" | 
|     default 100 | 
|     range 0 4096 | 
|     depends on GCC_PLUGIN_STACKLEAK | 
|     help | 
|       The STACKLEAK gcc plugin instruments the kernel code for tracking | 
|       the lowest border of the kernel stack (and for some other purposes). | 
|       It inserts the stackleak_track_stack() call for the functions with | 
|       a stack frame size greater than or equal to this parameter. | 
|       If unsure, leave the default value 100. | 
|   | 
| config STACKLEAK_METRICS | 
|     bool "Show STACKLEAK metrics in the /proc file system" | 
|     depends on GCC_PLUGIN_STACKLEAK | 
|     depends on PROC_FS | 
|     help | 
|       If this is set, STACKLEAK metrics for every task are available in | 
|       the /proc file system. In particular, /proc/<pid>/stack_depth | 
|       shows the maximum kernel stack consumption for the current and | 
|       previous syscalls. Although this information is not precise, it | 
|       can be useful for estimating the STACKLEAK performance impact for | 
|       your workloads. | 
|   | 
| config STACKLEAK_RUNTIME_DISABLE | 
|     bool "Allow runtime disabling of kernel stack erasing" | 
|     depends on GCC_PLUGIN_STACKLEAK | 
|     help | 
|       This option provides 'stack_erasing' sysctl, which can be used in | 
|       runtime to control kernel stack erasing for kernels built with | 
|       CONFIG_GCC_PLUGIN_STACKLEAK. | 
|   | 
| config INIT_ON_ALLOC_DEFAULT_ON | 
|     bool "Enable heap memory zeroing on allocation by default" | 
|     help | 
|       This has the effect of setting "init_on_alloc=1" on the kernel | 
|       command line. This can be disabled with "init_on_alloc=0". | 
|       When "init_on_alloc" is enabled, all page allocator and slab | 
|       allocator memory will be zeroed when allocated, eliminating | 
|       many kinds of "uninitialized heap memory" flaws, especially | 
|       heap content exposures. The performance impact varies by | 
|       workload, but most cases see <1% impact. Some synthetic | 
|       workloads have measured as high as 7%. | 
|   | 
| config INIT_ON_FREE_DEFAULT_ON | 
|     bool "Enable heap memory zeroing on free by default" | 
|     help | 
|       This has the effect of setting "init_on_free=1" on the kernel | 
|       command line. This can be disabled with "init_on_free=0". | 
|       Similar to "init_on_alloc", when "init_on_free" is enabled, | 
|       all page allocator and slab allocator memory will be zeroed | 
|       when freed, eliminating many kinds of "uninitialized heap memory" | 
|       flaws, especially heap content exposures. The primary difference | 
|       with "init_on_free" is that data lifetime in memory is reduced, | 
|       as anything freed is wiped immediately, making live forensics or | 
|       cold boot memory attacks unable to recover freed memory contents. | 
|       The performance impact varies by workload, but is more expensive | 
|       than "init_on_alloc" due to the negative cache effects of | 
|       touching "cold" memory areas. Most cases see 3-5% impact. Some | 
|       synthetic workloads have measured as high as 8%. | 
|   | 
| endmenu | 
|   | 
| endmenu |