382 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			382 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
# 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)"
 | 
						|
		# Plugin can be removed once the kernel only supports GCC 12+
 | 
						|
		depends on GCC_PLUGINS && !CC_HAS_AUTO_VAR_INIT_ZERO
 | 
						|
		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)"
 | 
						|
		# Plugin can be removed once the kernel only supports GCC 12+
 | 
						|
		depends on GCC_PLUGINS && !CC_HAS_AUTO_VAR_INIT_ZERO
 | 
						|
		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)"
 | 
						|
		# Plugin can be removed once the kernel only supports GCC 12+
 | 
						|
		depends on GCC_PLUGINS && !CC_HAS_AUTO_VAR_INIT_ZERO
 | 
						|
		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
 | 
						|
		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.
 | 
						|
 | 
						|
	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 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 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 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"
 | 
						|
	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 "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 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
 | 
						|
		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
 | 
						|
		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
 |