security: Implement Clang's stack initialization

CONFIG_INIT_STACK_ALL turns on stack initialization based on
-ftrivial-auto-var-init in Clang builds, which has greater coverage
than CONFIG_GCC_PLUGINS_STRUCTLEAK_BYREF_ALL.

-ftrivial-auto-var-init Clang option provides trivial initializers for
uninitialized local variables, variable fields and padding.

It has three possible values:
  pattern - uninitialized locals are filled with a fixed pattern
    (mostly 0xAA on 64-bit platforms, see https://reviews.llvm.org/D54604
    for more details, but 0x000000AA for 32-bit pointers) likely to cause
    crashes when uninitialized value is used;
  zero (it's still debated whether this flag makes it to the official
    Clang release) - uninitialized locals are filled with zeroes;
  uninitialized (default) - uninitialized locals are left intact.

This patch uses only the "pattern" mode when CONFIG_INIT_STACK_ALL is
enabled.

Developers have the possibility to opt-out of this feature on a
per-variable basis by using __attribute__((uninitialized)), but such
use should be well justified in comments.

Co-developed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Tested-by: Alexander Potapenko <glider@google.com>
Acked-by: Masahiro Yamada <yamada.masahiro@socionext.com>
This commit is contained in:
Kees Cook 2019-04-10 08:48:31 -07:00
parent b6a6a3772d
commit 709a972efb
2 changed files with 19 additions and 0 deletions

View File

@ -745,6 +745,11 @@ KBUILD_CFLAGS += -fomit-frame-pointer
endif endif
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) DEBUG_CFLAGS := $(call cc-option, -fno-var-tracking-assignments)
ifdef CONFIG_DEBUG_INFO ifdef CONFIG_DEBUG_INFO

View File

@ -18,9 +18,13 @@ config GCC_PLUGIN_STRUCTLEAK
menu "Memory initialization" menu "Memory initialization"
config CC_HAS_AUTO_VAR_INIT
def_bool $(cc-option,-ftrivial-auto-var-init=pattern)
choice choice
prompt "Initialize kernel stack variables at function entry" prompt "Initialize kernel stack variables at function entry"
default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS 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 default INIT_STACK_NONE
help help
This option enables initialization of stack variables at This option enables initialization of stack variables at
@ -76,6 +80,16 @@ choice
of uninitialized stack variable exploits and information of uninitialized stack variable exploits and information
exposures. 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 endchoice
config GCC_PLUGIN_STRUCTLEAK_VERBOSE config GCC_PLUGIN_STRUCTLEAK_VERBOSE