| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- # 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
- def_bool $(cc-option,-fzero-call-used-regs=used-gpr)
- # https://github.com/ClangBuiltLinux/linux/issues/1766
- # https://github.com/llvm/llvm-project/issues/59242
- depends on !CC_IS_CLANG || CLANG_VERSION > 150006
- 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
- # https://github.com/llvm/llvm-project/issues/53645
- depends on !X86_32 || !CC_IS_CLANG || CLANG_VERSION >= 160000
- 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)
- # Randstruct was first added in Clang 15, but it isn't safe to use until
- # Clang 16 due to https://github.com/llvm/llvm-project/issues/60349
- depends on !CC_IS_CLANG || CLANG_VERSION >= 160000
- 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
|