| # SPDX-License-Identifier: GPL-2.0-only | |
| menu "Kernel hardening options" | |
| 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 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 INIT_STACK_ALL_PATTERN | |
| bool "pattern-init everything (strongest)" | |
| depends on CC_HAS_AUTO_VAR_INIT_PATTERN | |
| depends on !KMSAN | |
| 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. | |
| GCC uses 0xFE repeating for all types, and zero for padding. | |
| config INIT_STACK_ALL_ZERO | |
| bool "zero-init everything (strongest and safest)" | |
| depends on CC_HAS_AUTO_VAR_INIT_ZERO | |
| depends on !KMSAN | |
| 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 CC_HAS_SANCOV_STACK_DEPTH_CALLBACK | |
| def_bool $(cc-option,-fsanitize-coverage-stack-depth-callback-min=1) | |
| config KSTACK_ERASE | |
| bool "Poison kernel stack before returning from syscalls" | |
| depends on HAVE_ARCH_KSTACK_ERASE | |
| depends on GCC_PLUGINS || CC_HAS_SANCOV_STACK_DEPTH_CALLBACK | |
| 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. | |
| config GCC_PLUGIN_STACKLEAK | |
| def_bool KSTACK_ERASE | |
| depends on GCC_PLUGINS | |
| help | |
| This plugin was ported from grsecurity/PaX. More information at: | |
| * https://grsecurity.net/ | |
| * https://pax.grsecurity.net/ | |
| config GCC_PLUGIN_STACKLEAK_VERBOSE | |
| bool "Report stack depth analysis instrumentation" if EXPERT | |
| depends on GCC_PLUGIN_STACKLEAK | |
| depends on !COMPILE_TEST # too noisy | |
| help | |
| This option will cause a warning to be printed each time the | |
| stackleak plugin finds a function it thinks needs to be | |
| instrumented. This is useful for comparing coverage between | |
| builds. | |
| config KSTACK_ERASE_TRACK_MIN_SIZE | |
| int "Minimum stack frame size of functions tracked by KSTACK_ERASE" | |
| default 100 | |
| range 0 4096 | |
| depends on KSTACK_ERASE | |
| help | |
| The KSTACK_ERASE option instruments the kernel code for tracking | |
| the lowest border of the kernel stack (and for some other purposes). | |
| It inserts the __sanitizer_cov_stack_depth() call for the functions | |
| with a stack frame size greater than or equal to this parameter. | |
| If unsure, leave the default value 100. | |
| config KSTACK_ERASE_METRICS | |
| bool "Show KSTACK_ERASE metrics in the /proc file system" | |
| depends on KSTACK_ERASE | |
| depends on PROC_FS | |
| help | |
| If this is set, KSTACK_ERASE 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 KSTACK_ERASE performance impact | |
| for your workloads. | |
| config KSTACK_ERASE_RUNTIME_DISABLE | |
| bool "Allow runtime disabling of kernel stack erasing" | |
| depends on KSTACK_ERASE | |
| help | |
| This option provides 'stack_erasing' sysctl, which can be used in | |
| runtime to control kernel stack erasing for kernels built with | |
| CONFIG_KSTACK_ERASE. | |
| config INIT_ON_ALLOC_DEFAULT_ON | |
| bool "Enable heap memory zeroing on allocation by default" | |
| depends on !KMSAN | |
| 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" | |
| depends on !KMSAN | |
| 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%. | |
| config CC_HAS_ZERO_CALL_USED_REGS | |
| # supported by gcc-11 or newer and all supported versions of clang | |
| def_bool $(cc-option,-fzero-call-used-regs=used-gpr) | |
| config ZERO_CALL_USED_REGS | |
| bool "Enable register zeroing on function exit" | |
| depends on CC_HAS_ZERO_CALL_USED_REGS | |
| help | |
| At the end of functions, always zero any caller-used register | |
| contents. This helps ensure that temporary values are not | |
| leaked beyond the function boundary. This means that register | |
| contents are less likely to be available for side channels | |
| and information exposures. Additionally, this helps reduce the | |
| number of useful ROP gadgets by about 20% (and removes compiler | |
| generated "write-what-where" gadgets) in the resulting kernel | |
| image. This has a less than 1% performance impact on most | |
| workloads. Image size growth depends on architecture, and should | |
| be evaluated for suitability. For example, x86_64 grows by less | |
| than 1%, and arm64 grows by about 5%. | |
| endmenu | |
| menu "Bounds checking" | |
| config FORTIFY_SOURCE | |
| bool "Harden common str/mem functions against buffer overflows" | |
| depends on ARCH_HAS_FORTIFY_SOURCE | |
| help | |
| Detect overflows of buffers in common string and memory functions | |
| where the compiler can determine and validate the buffer sizes. | |
| config HARDENED_USERCOPY | |
| bool "Harden memory copies between kernel and userspace" | |
| imply STRICT_DEVMEM | |
| help | |
| This option checks for obviously wrong memory regions when | |
| copying memory to/from the kernel (via copy_to_user() and | |
| copy_from_user() functions) by rejecting memory ranges that | |
| are larger than the specified heap object, span multiple | |
| separately allocated pages, are not on the process stack, | |
| or are part of the kernel text. This prevents entire classes | |
| of heap overflow exploits and similar kernel memory exposures. | |
| config HARDENED_USERCOPY_DEFAULT_ON | |
| bool "Harden memory copies by default" | |
| depends on HARDENED_USERCOPY | |
| default HARDENED_USERCOPY | |
| help | |
| This has the effect of setting "hardened_usercopy=on" on the kernel | |
| command line. This can be disabled with "hardened_usercopy=off". | |
| endmenu | |
| menu "Hardening of kernel data structures" | |
| config LIST_HARDENED | |
| bool "Check integrity of linked list manipulation" | |
| help | |
| Minimal integrity checking in the linked-list manipulation routines | |
| to catch memory corruptions that are not guaranteed to result in an | |
| immediate access fault. | |
| If unsure, say N. | |
| config RUST_BITMAP_HARDENED | |
| bool "Check integrity of bitmap Rust API" | |
| depends on RUST | |
| help | |
| Enables additional assertions in the Rust Bitmap API to catch | |
| arguments that are not guaranteed to result in an immediate access | |
| fault. | |
| If unsure, say N. | |
| config BUG_ON_DATA_CORRUPTION | |
| bool "Trigger a BUG when data corruption is detected" | |
| select LIST_HARDENED | |
| help | |
| Select this option if the kernel should BUG when it encounters | |
| data corruption in kernel memory structures when they get checked | |
| for validity. | |
| If unsure, say N. | |
| endmenu | |
| config CC_HAS_RANDSTRUCT | |
| def_bool $(cc-option,-frandomize-layout-seed-file=/dev/null) | |
| choice | |
| prompt "Randomize layout of sensitive kernel structures" | |
| default RANDSTRUCT_FULL if COMPILE_TEST && (GCC_PLUGINS || CC_HAS_RANDSTRUCT) | |
| default RANDSTRUCT_NONE | |
| help | |
| If you enable this, the layouts of structures that are entirely | |
| function pointers (and have not been manually annotated with | |
| __no_randomize_layout), or structures that have been explicitly | |
| marked with __randomize_layout, will be randomized at compile-time. | |
| This can introduce the requirement of an additional information | |
| exposure vulnerability for exploits targeting these structure | |
| types. | |
| Enabling this feature will introduce some performance impact, | |
| slightly increase memory usage, and prevent the use of forensic | |
| tools like Volatility against the system (unless the kernel | |
| source tree isn't cleaned after kernel installation). | |
| The seed used for compilation is in scripts/basic/randomize.seed. | |
| It remains after a "make clean" to allow for external modules to | |
| be compiled with the existing seed and will be removed by a | |
| "make mrproper" or "make distclean". This file should not be made | |
| public, or the structure layout can be determined. | |
| config RANDSTRUCT_NONE | |
| bool "Disable structure layout randomization" | |
| help | |
| Build normally: no structure layout randomization. | |
| config RANDSTRUCT_FULL | |
| bool "Fully randomize structure layout" | |
| depends on CC_HAS_RANDSTRUCT || GCC_PLUGINS | |
| select MODVERSIONS if MODULES && !COMPILE_TEST | |
| help | |
| Fully randomize the member layout of sensitive | |
| structures as much as possible, which may have both a | |
| memory size and performance impact. | |
| One difference between the Clang and GCC plugin | |
| implementations is the handling of bitfields. The GCC | |
| plugin treats them as fully separate variables, | |
| introducing sometimes significant padding. Clang tries | |
| to keep adjacent bitfields together, but with their bit | |
| ordering randomized. | |
| config RANDSTRUCT_PERFORMANCE | |
| bool "Limit randomization of structure layout to cache-lines" | |
| depends on GCC_PLUGINS | |
| select MODVERSIONS if MODULES && !COMPILE_TEST | |
| help | |
| Randomization of sensitive kernel structures will make a | |
| best effort at restricting randomization to cacheline-sized | |
| groups of members. It will further not randomize bitfields | |
| in structures. This reduces the performance hit of RANDSTRUCT | |
| at the cost of weakened randomization. | |
| endchoice | |
| config RANDSTRUCT | |
| def_bool !RANDSTRUCT_NONE | |
| config GCC_PLUGIN_RANDSTRUCT | |
| def_bool GCC_PLUGINS && RANDSTRUCT | |
| help | |
| Use GCC plugin to randomize structure layout. | |
| This plugin was ported from grsecurity/PaX. More | |
| information at: | |
| * https://grsecurity.net/ | |
| * https://pax.grsecurity.net/ | |
| endmenu |