compiler-based memory initialization
- Consolidate memory initialization Kconfigs (Kees) - Implement support for Clang's stack variable auto-init (Alexander) -----BEGIN PGP SIGNATURE----- Comment: Kees Cook <kees@outflux.net> iQJKBAABCgA0FiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAlzQafUWHGtlZXNjb29r QGNocm9taXVtLm9yZwAKCRCJcvTf3G3AJrTfEAChweGM23u8i0vOgGM4fYAXr9di THoKkgEGgQJJaArgElEuZgwos8uhH2rGhQ2zcY38ZFA20byBZ/G8jFNXNuzFgUyQ 6p5DUU2P2qam+v/cXvFqBqbXg4VzmlwR6Lzi9DHZ3XC41kz5YUWqHTq3md1uCU82 V2Z0V3xF7Zvjx14V42UzEqW66l3dUrYPOFSJVTCMC5vaJvov3gFjStRkYuSzYg+N 1ns7SdT8sQvXeAoj1VSeunNuv8iCVytFWC6f0cIs3iCt9nD/IYk1d9Zl6MAqive2 5sKDhUKBzg03xB1rztDmxZKAyN3YYoZFfJr3PruSvUiMxYYtX3IMvKFI257RQl8J WYP5qa0kHHM1uel5kS4fckzAv+oqNnnXgdSy5ajc1YFcdBxwiy6DfvBjk843DyU/ +OLb1wh5Uz6ICg6GILgVoL5nZinnj73zgj78bfRemiy1j7LZVtkX0EDAwIJxE2U9 SYYeEvUu91jNbkE9ugu8RXmXv1QctOuiBr70VLupVu/a7AJij6Cq8Ox9uge25DRF XnuVjXCpMdx6p6i1kaNXZtxREK4at0J2CCIqGyzFpRgym2OpyJBIgVEWDMsfof0w HOKUpbp7TytVdRoEWcwU32oGBa/e0PbJ2KSNK0t+5bKeIOTxFJf1qeWwaWXu3JQE DRYx7/sVHjGUXsSNeg== =i0Gi -----END PGP SIGNATURE----- Merge tag 'meminit-v5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull compiler-based variable initialization updates from Kees Cook: "This is effectively part of my gcc-plugins tree, but as this adds some Clang support, it felt weird to still call it "gcc-plugins". :) This consolidates Kconfig for the existing stack variable initialization (via structleak and stackleak gcc plugins) and adds Alexander Potapenko's support for Clang's new similar functionality. Summary: - Consolidate memory initialization Kconfigs (Kees) - Implement support for Clang's stack variable auto-init (Alexander)" * tag 'meminit-v5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: security: Implement Clang's stack initialization security: Move stackleak config to Kconfig.hardening security: Create "kernel hardening" config area
This commit is contained in:
commit
2d60d96b6f
5
Makefile
5
Makefile
@ -748,6 +748,11 @@ KBUILD_CFLAGS += -fomit-frame-pointer
|
||||
endif
|
||||
endif
|
||||
|
||||
# Initialize all stack variables with a pattern, if desired.
|
||||
ifdef CONFIG_INIT_STACK_ALL
|
||||
KBUILD_CFLAGS += -ftrivial-auto-var-init=pattern
|
||||
endif
|
||||
|
||||
DEBUG_CFLAGS := $(call cc-option, -fno-var-tracking-assignments)
|
||||
|
||||
ifdef CONFIG_DEBUG_INFO
|
||||
|
@ -13,17 +13,19 @@ config HAVE_GCC_PLUGINS
|
||||
An arch should select this symbol if it supports building with
|
||||
GCC plugins.
|
||||
|
||||
menuconfig GCC_PLUGINS
|
||||
bool "GCC plugins"
|
||||
config GCC_PLUGINS
|
||||
bool
|
||||
depends on HAVE_GCC_PLUGINS
|
||||
depends on PLUGIN_HOSTCC != ""
|
||||
default y
|
||||
help
|
||||
GCC plugins are loadable modules that provide extra features to the
|
||||
compiler. They are useful for runtime instrumentation and static analysis.
|
||||
|
||||
See Documentation/gcc-plugins.txt for details.
|
||||
|
||||
if GCC_PLUGINS
|
||||
menu "GCC plugins"
|
||||
depends on GCC_PLUGINS
|
||||
|
||||
config GCC_PLUGIN_CYC_COMPLEXITY
|
||||
bool "Compute the cyclomatic complexity of a function" if EXPERT
|
||||
@ -66,71 +68,6 @@ config GCC_PLUGIN_LATENT_ENTROPY
|
||||
* https://grsecurity.net/
|
||||
* https://pax.grsecurity.net/
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK
|
||||
bool "Zero initialize stack variables"
|
||||
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/
|
||||
|
||||
choice
|
||||
prompt "Coverage"
|
||||
depends on GCC_PLUGIN_STRUCTLEAK
|
||||
default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
|
||||
help
|
||||
This chooses the level of coverage over classes of potentially
|
||||
uninitialized variables. The selected class will be
|
||||
zero-initialized before use.
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK_USER
|
||||
bool "structs marked for userspace"
|
||||
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 "structs passed by reference"
|
||||
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
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
|
||||
bool "anything passed by reference"
|
||||
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.
|
||||
|
||||
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_RANDSTRUCT
|
||||
bool "Randomize layout of sensitive kernel structures"
|
||||
select MODVERSIONS if MODULES
|
||||
@ -171,59 +108,8 @@ config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE
|
||||
in structures. This reduces the performance hit of RANDSTRUCT
|
||||
at the cost of weakened randomization.
|
||||
|
||||
config GCC_PLUGIN_STACKLEAK
|
||||
bool "Erase the 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. That reduces the information which
|
||||
kernel stack leak bugs can reveal and blocks some uninitialized
|
||||
stack variable attacks.
|
||||
|
||||
The tradeoff is 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 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 GCC_PLUGIN_ARM_SSP_PER_TASK
|
||||
bool
|
||||
depends on GCC_PLUGINS && ARM
|
||||
|
||||
endif
|
||||
endmenu
|
||||
|
@ -287,5 +287,7 @@ config LSM
|
||||
|
||||
If unsure, leave this as the default.
|
||||
|
||||
source "security/Kconfig.hardening"
|
||||
|
||||
endmenu
|
||||
|
||||
|
164
security/Kconfig.hardening
Normal file
164
security/Kconfig.hardening
Normal file
@ -0,0 +1,164 @@
|
||||
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
|
||||
def_bool $(cc-option,-ftrivial-auto-var-init=pattern)
|
||||
|
||||
choice
|
||||
prompt "Initialize kernel stack variables at function entry"
|
||||
default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS
|
||||
default INIT_STACK_ALL if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT
|
||||
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 will be
|
||||
initialized before use in a function.
|
||||
|
||||
config INIT_STACK_NONE
|
||||
bool "no automatic 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)"
|
||||
depends on GCC_PLUGINS
|
||||
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)"
|
||||
depends on GCC_PLUGINS
|
||||
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
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
|
||||
bool "zero-init anything passed by reference (very strong)"
|
||||
depends on GCC_PLUGINS
|
||||
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.
|
||||
|
||||
config INIT_STACK_ALL
|
||||
bool "0xAA-init everything on the stack (strongest)"
|
||||
depends on CC_HAS_AUTO_VAR_INIT
|
||||
help
|
||||
Initializes everything on the stack with a 0xAA
|
||||
pattern. This is intended to eliminate all classes
|
||||
of uninitialized stack variable exploits and information
|
||||
exposures, even variables that were warned to have been
|
||||
left uninitialized.
|
||||
|
||||
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 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.
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
Loading…
Reference in New Issue
Block a user