Skip to content

Commit f0fe00d

Browse files
ramosian-gliderkees
authored andcommitted
security: allow using Clang's zero initialization for stack variables
In addition to -ftrivial-auto-var-init=pattern (used by CONFIG_INIT_STACK_ALL now) Clang also supports zero initialization for locals enabled by -ftrivial-auto-var-init=zero. The future of this flag is still being debated (see https://bugs.llvm.org/show_bug.cgi?id=45497). Right now it is guarded by another flag, -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang, which means it may not be supported by future Clang releases. Another possible resolution is that -ftrivial-auto-var-init=zero will persist (as certain users have already started depending on it), but the name of the guard flag will change. In the meantime, zero initialization has proven itself as a good production mitigation measure against uninitialized locals. Unlike pattern initialization, which has a higher chance of triggering existing bugs, zero initialization provides safe defaults for strings, pointers, indexes, and sizes. On the other hand, pattern initialization remains safer for return values. Chrome OS and Android are moving to using zero initialization for production builds. Performance-wise, the difference between pattern and zero initialization is usually negligible, although the generated code for zero initialization is more compact. This patch renames CONFIG_INIT_STACK_ALL to CONFIG_INIT_STACK_ALL_PATTERN and introduces another config option, CONFIG_INIT_STACK_ALL_ZERO, that enables zero initialization for locals if the corresponding flags are supported by Clang. Cc: Kees Cook <[email protected]> Cc: Nick Desaulniers <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Signed-off-by: Alexander Potapenko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Maciej Żenczykowski <[email protected]> Signed-off-by: Kees Cook <[email protected]>
1 parent b3a9e3b commit f0fe00d

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

Makefile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,11 +802,20 @@ KBUILD_CFLAGS += -fomit-frame-pointer
802802
endif
803803
endif
804804

805-
# Initialize all stack variables with a pattern, if desired.
806-
ifdef CONFIG_INIT_STACK_ALL
805+
# Initialize all stack variables with a 0xAA pattern.
806+
ifdef CONFIG_INIT_STACK_ALL_PATTERN
807807
KBUILD_CFLAGS += -ftrivial-auto-var-init=pattern
808808
endif
809809

810+
# Initialize all stack variables with a zero value.
811+
ifdef CONFIG_INIT_STACK_ALL_ZERO
812+
# Future support for zero initialization is still being debated, see
813+
# https://bugs.llvm.org/show_bug.cgi?id=45497. These flags are subject to being
814+
# renamed or dropped.
815+
KBUILD_CFLAGS += -ftrivial-auto-var-init=zero
816+
KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang
817+
endif
818+
810819
DEBUG_CFLAGS := $(call cc-option, -fno-var-tracking-assignments)
811820

812821
ifdef CONFIG_DEBUG_INFO

init/main.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -779,14 +779,16 @@ static void __init report_meminit(void)
779779
{
780780
const char *stack;
781781

782-
if (IS_ENABLED(CONFIG_INIT_STACK_ALL))
783-
stack = "all";
782+
if (IS_ENABLED(CONFIG_INIT_STACK_ALL_PATTERN))
783+
stack = "all(pattern)";
784+
else if (IS_ENABLED(CONFIG_INIT_STACK_ALL_ZERO))
785+
stack = "all(zero)";
784786
else if (IS_ENABLED(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL))
785-
stack = "byref_all";
787+
stack = "byref_all(zero)";
786788
else if (IS_ENABLED(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF))
787-
stack = "byref";
789+
stack = "byref(zero)";
788790
else if (IS_ENABLED(CONFIG_GCC_PLUGIN_STRUCTLEAK_USER))
789-
stack = "__user";
791+
stack = "__user(zero)";
790792
else
791793
stack = "off";
792794

security/Kconfig.hardening

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ config GCC_PLUGIN_STRUCTLEAK
1919

2020
menu "Memory initialization"
2121

22-
config CC_HAS_AUTO_VAR_INIT
22+
config CC_HAS_AUTO_VAR_INIT_PATTERN
2323
def_bool $(cc-option,-ftrivial-auto-var-init=pattern)
2424

25+
config CC_HAS_AUTO_VAR_INIT_ZERO
26+
def_bool $(cc-option,-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang)
27+
2528
choice
2629
prompt "Initialize kernel stack variables at function entry"
2730
default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS
28-
default INIT_STACK_ALL if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT
31+
default INIT_STACK_ALL_PATTERN if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT_PATTERN
2932
default INIT_STACK_NONE
3033
help
3134
This option enables initialization of stack variables at
@@ -88,16 +91,34 @@ choice
8891
of uninitialized stack variable exploits and information
8992
exposures.
9093

91-
config INIT_STACK_ALL
94+
config INIT_STACK_ALL_PATTERN
9295
bool "0xAA-init everything on the stack (strongest)"
93-
depends on CC_HAS_AUTO_VAR_INIT
96+
depends on CC_HAS_AUTO_VAR_INIT_PATTERN
9497
help
9598
Initializes everything on the stack with a 0xAA
9699
pattern. This is intended to eliminate all classes
97100
of uninitialized stack variable exploits and information
98101
exposures, even variables that were warned to have been
99102
left uninitialized.
100103

104+
Pattern initialization is known to provoke many existing bugs
105+
related to uninitialized locals, e.g. pointers receive
106+
non-NULL values, buffer sizes and indices are very big.
107+
108+
config INIT_STACK_ALL_ZERO
109+
bool "zero-init everything on the stack (strongest and safest)"
110+
depends on CC_HAS_AUTO_VAR_INIT_ZERO
111+
help
112+
Initializes everything on the stack with a zero
113+
value. This is intended to eliminate all classes
114+
of uninitialized stack variable exploits and information
115+
exposures, even variables that were warned to have been
116+
left uninitialized.
117+
118+
Zero initialization provides safe defaults for strings,
119+
pointers, indices and sizes, and is therefore
120+
more suitable as a security mitigation measure.
121+
101122
endchoice
102123

103124
config GCC_PLUGIN_STRUCTLEAK_VERBOSE

0 commit comments

Comments
 (0)