linux/security/Kconfig.hardening
<<
>>
Prefs
   1# SPDX-License-Identifier: GPL-2.0-only
   2menu "Kernel hardening options"
   3
   4config GCC_PLUGIN_STRUCTLEAK
   5        bool
   6        help
   7          While the kernel is built with warnings enabled for any missed
   8          stack variable initializations, this warning is silenced for
   9          anything passed by reference to another function, under the
  10          occasionally misguided assumption that the function will do
  11          the initialization. As this regularly leads to exploitable
  12          flaws, this plugin is available to identify and zero-initialize
  13          such variables, depending on the chosen level of coverage.
  14
  15          This plugin was originally ported from grsecurity/PaX. More
  16          information at:
  17           * https://grsecurity.net/
  18           * https://pax.grsecurity.net/
  19
  20menu "Memory initialization"
  21
  22config CC_HAS_AUTO_VAR_INIT_PATTERN
  23        def_bool $(cc-option,-ftrivial-auto-var-init=pattern)
  24
  25config CC_HAS_AUTO_VAR_INIT_ZERO_BARE
  26        def_bool $(cc-option,-ftrivial-auto-var-init=zero)
  27
  28config CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER
  29        # Clang 16 and later warn about using the -enable flag, but it
  30        # is required before then.
  31        def_bool $(cc-option,-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang)
  32        depends on !CC_HAS_AUTO_VAR_INIT_ZERO_BARE
  33
  34config CC_HAS_AUTO_VAR_INIT_ZERO
  35        def_bool CC_HAS_AUTO_VAR_INIT_ZERO_BARE || CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER
  36
  37choice
  38        prompt "Initialize kernel stack variables at function entry"
  39        default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS
  40        default INIT_STACK_ALL_PATTERN if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT_PATTERN
  41        default INIT_STACK_ALL_ZERO if CC_HAS_AUTO_VAR_INIT_ZERO
  42        default INIT_STACK_NONE
  43        help
  44          This option enables initialization of stack variables at
  45          function entry time. This has the possibility to have the
  46          greatest coverage (since all functions can have their
  47          variables initialized), but the performance impact depends
  48          on the function calling complexity of a given workload's
  49          syscalls.
  50
  51          This chooses the level of coverage over classes of potentially
  52          uninitialized variables. The selected class of variable will be
  53          initialized before use in a function.
  54
  55        config INIT_STACK_NONE
  56                bool "no automatic stack variable initialization (weakest)"
  57                help
  58                  Disable automatic stack variable initialization.
  59                  This leaves the kernel vulnerable to the standard
  60                  classes of uninitialized stack variable exploits
  61                  and information exposures.
  62
  63        config GCC_PLUGIN_STRUCTLEAK_USER
  64                bool "zero-init structs marked for userspace (weak)"
  65                # Plugin can be removed once the kernel only supports GCC 12+
  66                depends on GCC_PLUGINS && !CC_HAS_AUTO_VAR_INIT_ZERO
  67                select GCC_PLUGIN_STRUCTLEAK
  68                help
  69                  Zero-initialize any structures on the stack containing
  70                  a __user attribute. This can prevent some classes of
  71                  uninitialized stack variable exploits and information
  72                  exposures, like CVE-2013-2141:
  73                  https://git.kernel.org/linus/b9e146d8eb3b9eca
  74
  75        config GCC_PLUGIN_STRUCTLEAK_BYREF
  76                bool "zero-init structs passed by reference (strong)"
  77                # Plugin can be removed once the kernel only supports GCC 12+
  78                depends on GCC_PLUGINS && !CC_HAS_AUTO_VAR_INIT_ZERO
  79                depends on !(KASAN && KASAN_STACK)
  80                select GCC_PLUGIN_STRUCTLEAK
  81                help
  82                  Zero-initialize any structures on the stack that may
  83                  be passed by reference and had not already been
  84                  explicitly initialized. This can prevent most classes
  85                  of uninitialized stack variable exploits and information
  86                  exposures, like CVE-2017-1000410:
  87                  https://git.kernel.org/linus/06e7e776ca4d3654
  88
  89                  As a side-effect, this keeps a lot of variables on the
  90                  stack that can otherwise be optimized out, so combining
  91                  this with CONFIG_KASAN_STACK can lead to a stack overflow
  92                  and is disallowed.
  93
  94        config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
  95                bool "zero-init everything passed by reference (very strong)"
  96                # Plugin can be removed once the kernel only supports GCC 12+
  97                depends on GCC_PLUGINS && !CC_HAS_AUTO_VAR_INIT_ZERO
  98                depends on !(KASAN && KASAN_STACK)
  99                select GCC_PLUGIN_STRUCTLEAK
 100                help
 101                  Zero-initialize any stack variables that may be passed
 102                  by reference and had not already been explicitly
 103                  initialized. This is intended to eliminate all classes
 104                  of uninitialized stack variable exploits and information
 105                  exposures.
 106
 107                  As a side-effect, this keeps a lot of variables on the
 108                  stack that can otherwise be optimized out, so combining
 109                  this with CONFIG_KASAN_STACK can lead to a stack overflow
 110                  and is disallowed.
 111
 112        config INIT_STACK_ALL_PATTERN
 113                bool "pattern-init everything (strongest)"
 114                depends on CC_HAS_AUTO_VAR_INIT_PATTERN
 115                depends on !KMSAN
 116                help
 117                  Initializes everything on the stack (including padding)
 118                  with a specific debug value. This is intended to eliminate
 119                  all classes of uninitialized stack variable exploits and
 120                  information exposures, even variables that were warned about
 121                  having been left uninitialized.
 122
 123                  Pattern initialization is known to provoke many existing bugs
 124                  related to uninitialized locals, e.g. pointers receive
 125                  non-NULL values, buffer sizes and indices are very big. The
 126                  pattern is situation-specific; Clang on 64-bit uses 0xAA
 127                  repeating for all types and padding except float and double
 128                  which use 0xFF repeating (-NaN). Clang on 32-bit uses 0xFF
 129                  repeating for all types and padding.
 130
 131        config INIT_STACK_ALL_ZERO
 132                bool "zero-init everything (strongest and safest)"
 133                depends on CC_HAS_AUTO_VAR_INIT_ZERO
 134                depends on !KMSAN
 135                help
 136                  Initializes everything on the stack (including padding)
 137                  with a zero value. This is intended to eliminate all
 138                  classes of uninitialized stack variable exploits and
 139                  information exposures, even variables that were warned
 140                  about having been left uninitialized.
 141
 142                  Zero initialization provides safe defaults for strings
 143                  (immediately NUL-terminated), pointers (NULL), indices
 144                  (index 0), and sizes (0 length), so it is therefore more
 145                  suitable as a production security mitigation than pattern
 146                  initialization.
 147
 148endchoice
 149
 150config GCC_PLUGIN_STRUCTLEAK_VERBOSE
 151        bool "Report forcefully initialized variables"
 152        depends on GCC_PLUGIN_STRUCTLEAK
 153        depends on !COMPILE_TEST        # too noisy
 154        help
 155          This option will cause a warning to be printed each time the
 156          structleak plugin finds a variable it thinks needs to be
 157          initialized. Since not all existing initializers are detected
 158          by the plugin, this can produce false positive warnings.
 159
 160config GCC_PLUGIN_STACKLEAK
 161        bool "Poison kernel stack before returning from syscalls"
 162        depends on GCC_PLUGINS
 163        depends on HAVE_ARCH_STACKLEAK
 164        help
 165          This option makes the kernel erase the kernel stack before
 166          returning from system calls. This has the effect of leaving
 167          the stack initialized to the poison value, which both reduces
 168          the lifetime of any sensitive stack contents and reduces
 169          potential for uninitialized stack variable exploits or information
 170          exposures (it does not cover functions reaching the same stack
 171          depth as prior functions during the same syscall). This blocks
 172          most uninitialized stack variable attacks, with the performance
 173          impact being driven by the depth of the stack usage, rather than
 174          the function calling complexity.
 175
 176          The performance impact on a single CPU system kernel compilation
 177          sees a 1% slowdown, other systems and workloads may vary and you
 178          are advised to test this feature on your expected workload before
 179          deploying it.
 180
 181          This plugin was ported from grsecurity/PaX. More information at:
 182           * https://grsecurity.net/
 183           * https://pax.grsecurity.net/
 184
 185config GCC_PLUGIN_STACKLEAK_VERBOSE
 186        bool "Report stack depth analysis instrumentation" if EXPERT
 187        depends on GCC_PLUGIN_STACKLEAK
 188        depends on !COMPILE_TEST        # too noisy
 189        help
 190          This option will cause a warning to be printed each time the
 191          stackleak plugin finds a function it thinks needs to be
 192          instrumented. This is useful for comparing coverage between
 193          builds.
 194
 195config STACKLEAK_TRACK_MIN_SIZE
 196        int "Minimum stack frame size of functions tracked by STACKLEAK"
 197        default 100
 198        range 0 4096
 199        depends on GCC_PLUGIN_STACKLEAK
 200        help
 201          The STACKLEAK gcc plugin instruments the kernel code for tracking
 202          the lowest border of the kernel stack (and for some other purposes).
 203          It inserts the stackleak_track_stack() call for the functions with
 204          a stack frame size greater than or equal to this parameter.
 205          If unsure, leave the default value 100.
 206
 207config STACKLEAK_METRICS
 208        bool "Show STACKLEAK metrics in the /proc file system"
 209        depends on GCC_PLUGIN_STACKLEAK
 210        depends on PROC_FS
 211        help
 212          If this is set, STACKLEAK metrics for every task are available in
 213          the /proc file system. In particular, /proc/<pid>/stack_depth
 214          shows the maximum kernel stack consumption for the current and
 215          previous syscalls. Although this information is not precise, it
 216          can be useful for estimating the STACKLEAK performance impact for
 217          your workloads.
 218
 219config STACKLEAK_RUNTIME_DISABLE
 220        bool "Allow runtime disabling of kernel stack erasing"
 221        depends on GCC_PLUGIN_STACKLEAK
 222        help
 223          This option provides 'stack_erasing' sysctl, which can be used in
 224          runtime to control kernel stack erasing for kernels built with
 225          CONFIG_GCC_PLUGIN_STACKLEAK.
 226
 227config INIT_ON_ALLOC_DEFAULT_ON
 228        bool "Enable heap memory zeroing on allocation by default"
 229        depends on !KMSAN
 230        help
 231          This has the effect of setting "init_on_alloc=1" on the kernel
 232          command line. This can be disabled with "init_on_alloc=0".
 233          When "init_on_alloc" is enabled, all page allocator and slab
 234          allocator memory will be zeroed when allocated, eliminating
 235          many kinds of "uninitialized heap memory" flaws, especially
 236          heap content exposures. The performance impact varies by
 237          workload, but most cases see <1% impact. Some synthetic
 238          workloads have measured as high as 7%.
 239
 240config INIT_ON_FREE_DEFAULT_ON
 241        bool "Enable heap memory zeroing on free by default"
 242        depends on !KMSAN
 243        help
 244          This has the effect of setting "init_on_free=1" on the kernel
 245          command line. This can be disabled with "init_on_free=0".
 246          Similar to "init_on_alloc", when "init_on_free" is enabled,
 247          all page allocator and slab allocator memory will be zeroed
 248          when freed, eliminating many kinds of "uninitialized heap memory"
 249          flaws, especially heap content exposures. The primary difference
 250          with "init_on_free" is that data lifetime in memory is reduced,
 251          as anything freed is wiped immediately, making live forensics or
 252          cold boot memory attacks unable to recover freed memory contents.
 253          The performance impact varies by workload, but is more expensive
 254          than "init_on_alloc" due to the negative cache effects of
 255          touching "cold" memory areas. Most cases see 3-5% impact. Some
 256          synthetic workloads have measured as high as 8%.
 257
 258config CC_HAS_ZERO_CALL_USED_REGS
 259        def_bool $(cc-option,-fzero-call-used-regs=used-gpr)
 260        # https://github.com/ClangBuiltLinux/linux/issues/1766
 261        # https://github.com/llvm/llvm-project/issues/59242
 262        depends on !CC_IS_CLANG || CLANG_VERSION > 150006
 263
 264config ZERO_CALL_USED_REGS
 265        bool "Enable register zeroing on function exit"
 266        depends on CC_HAS_ZERO_CALL_USED_REGS
 267        help
 268          At the end of functions, always zero any caller-used register
 269          contents. This helps ensure that temporary values are not
 270          leaked beyond the function boundary. This means that register
 271          contents are less likely to be available for side channels
 272          and information exposures. Additionally, this helps reduce the
 273          number of useful ROP gadgets by about 20% (and removes compiler
 274          generated "write-what-where" gadgets) in the resulting kernel
 275          image. This has a less than 1% performance impact on most
 276          workloads. Image size growth depends on architecture, and should
 277          be evaluated for suitability. For example, x86_64 grows by less
 278          than 1%, and arm64 grows by about 5%.
 279
 280endmenu
 281
 282menu "Hardening of kernel data structures"
 283
 284config LIST_HARDENED
 285        bool "Check integrity of linked list manipulation"
 286        help
 287          Minimal integrity checking in the linked-list manipulation routines
 288          to catch memory corruptions that are not guaranteed to result in an
 289          immediate access fault.
 290
 291          If unsure, say N.
 292
 293config BUG_ON_DATA_CORRUPTION
 294        bool "Trigger a BUG when data corruption is detected"
 295        select LIST_HARDENED
 296        help
 297          Select this option if the kernel should BUG when it encounters
 298          data corruption in kernel memory structures when they get checked
 299          for validity.
 300
 301          If unsure, say N.
 302
 303endmenu
 304
 305config CC_HAS_RANDSTRUCT
 306        def_bool $(cc-option,-frandomize-layout-seed-file=/dev/null)
 307        # Randstruct was first added in Clang 15, but it isn't safe to use until
 308        # Clang 16 due to https://github.com/llvm/llvm-project/issues/60349
 309        depends on !CC_IS_CLANG || CLANG_VERSION >= 160000
 310
 311choice
 312        prompt "Randomize layout of sensitive kernel structures"
 313        default RANDSTRUCT_FULL if COMPILE_TEST && (GCC_PLUGINS || CC_HAS_RANDSTRUCT)
 314        default RANDSTRUCT_NONE
 315        help
 316          If you enable this, the layouts of structures that are entirely
 317          function pointers (and have not been manually annotated with
 318          __no_randomize_layout), or structures that have been explicitly
 319          marked with __randomize_layout, will be randomized at compile-time.
 320          This can introduce the requirement of an additional information
 321          exposure vulnerability for exploits targeting these structure
 322          types.
 323
 324          Enabling this feature will introduce some performance impact,
 325          slightly increase memory usage, and prevent the use of forensic
 326          tools like Volatility against the system (unless the kernel
 327          source tree isn't cleaned after kernel installation).
 328
 329          The seed used for compilation is in scripts/basic/randomize.seed.
 330          It remains after a "make clean" to allow for external modules to
 331          be compiled with the existing seed and will be removed by a
 332          "make mrproper" or "make distclean". This file should not be made
 333          public, or the structure layout can be determined.
 334
 335        config RANDSTRUCT_NONE
 336                bool "Disable structure layout randomization"
 337                help
 338                  Build normally: no structure layout randomization.
 339
 340        config RANDSTRUCT_FULL
 341                bool "Fully randomize structure layout"
 342                depends on CC_HAS_RANDSTRUCT || GCC_PLUGINS
 343                select MODVERSIONS if MODULES
 344                help
 345                  Fully randomize the member layout of sensitive
 346                  structures as much as possible, which may have both a
 347                  memory size and performance impact.
 348
 349                  One difference between the Clang and GCC plugin
 350                  implementations is the handling of bitfields. The GCC
 351                  plugin treats them as fully separate variables,
 352                  introducing sometimes significant padding. Clang tries
 353                  to keep adjacent bitfields together, but with their bit
 354                  ordering randomized.
 355
 356        config RANDSTRUCT_PERFORMANCE
 357                bool "Limit randomization of structure layout to cache-lines"
 358                depends on GCC_PLUGINS
 359                select MODVERSIONS if MODULES
 360                help
 361                  Randomization of sensitive kernel structures will make a
 362                  best effort at restricting randomization to cacheline-sized
 363                  groups of members. It will further not randomize bitfields
 364                  in structures. This reduces the performance hit of RANDSTRUCT
 365                  at the cost of weakened randomization.
 366endchoice
 367
 368config RANDSTRUCT
 369        def_bool !RANDSTRUCT_NONE
 370
 371config GCC_PLUGIN_RANDSTRUCT
 372        def_bool GCC_PLUGINS && RANDSTRUCT
 373        help
 374          Use GCC plugin to randomize structure layout.
 375
 376          This plugin was ported from grsecurity/PaX. More
 377          information at:
 378           * https://grsecurity.net/
 379           * https://pax.grsecurity.net/
 380
 381endmenu
 382