359 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			359 lines
		
	
	
		
			14 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
 | |
| 
 | |
| 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
 |