On Wed, Jun 15, 2016 at 2:26 PM, Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote: > On Wed, 15 Jun 2016 10:43:34 -0700 Kees Cook <keescook@xxxxxxxxxxxx> wrote: > >> >> I don't even get that far with that .config. With gcc-4.4.4 I get >> >> >> >> init/built-in.o: In function `initcall_blacklisted': >> >> main.c:(.text+0x41): undefined reference to `__stack_chk_guard' >> >> main.c:(.text+0xbe): undefined reference to `__stack_chk_guard' >> >> init/built-in.o: In function `do_one_initcall': >> >> (.text+0xeb): undefined reference to `__stack_chk_guard' >> >> init/built-in.o: In function `do_one_initcall': >> >> (.text+0x22b): undefined reference to `__stack_chk_guard' >> >> init/built-in.o: In function `name_to_dev_t': >> >> (.text+0x320): undefined reference to `__stack_chk_guard' >> >> init/built-in.o:(.text+0x52e): more undefined references to `__stack_chk_guard' >> > >> > This, I don't. I'm scratching my head about how that's possible. The >> > __stack_chk_guard is a compiler alias on x86... >> > >> >> Kees touched it last :) >> > >> > I'll take a closer look tomorrow... >> >> Stupid question: were you doing a build for x86? > > Yes, x86_64. Using Fengguang's .config.gz Okay, just wanted to double check since my head was spinning. :) >> This error really >> shouldn't be possible since gcc defaults to tls for the guard on x86. >> I don't have gcc 4.4.4 easily available, but I don't think it even has >> the -mstack-protector-guard option to force this to change. (And I see >> no reference to this option in the kernel tree.) AFAICT this error >> should only happen when building with either >> -mstack-protector-guard=global or an architecture that forces that, >> along with some new code that triggers the stack protector but lacks >> the symbol at link time, which also seems impossible. :P > > With gcc-4.8.4: > > make V=1 init/main.o > ... > gcc -Wp,-MD,init/.main.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/include -I./arch/x86/include -Iarch/x86/include/generated/uapi -Iarch/x86/include/generated -Iinclude -I./arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fn > o-asynchronous-unwind-tables -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -Wframe-larger-than=2048 -fstack-protector -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -DCC_HAVE_ASM_GOTO -DKBUILD_BASENAME='"main"' -DKBUILD_MODNAME='"main"' -c -o init/.tmp_main.o init/main.c > > (note: -fstack-protector) This is correct (the .config specifies CONFIG_CC_STACKPROTECTOR_REGULAR). > akpm3:/usr/src/25> nm init/main.o | grep chk > U __stack_chk_fail This is also correct: a stack protector was added, so on failure, __stack_chk_fail is called. This is correctly putting the stack protector guard into %gs (see arch/x86/include/asm/stackprotector.h for the dark magic/details). > With gcc-4.4.4: > > /opt/crosstool/gcc-4.4.4-nolibc/x86_64-linux/bin/x86_64-linux-gcc -Wp,-MD,init/.main.o.d -nostdinc -isystem /opt/crosstool/gcc-4.4.4-nolibc/x86_64-linux/bin/../lib/gcc/x86_64-linux/4.4.4/include -I./arch/x86/include -Iarch/x86/include/generated/uapi -Iarch/x86/include/generated -Iinclude -I./arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -pipe -Wno-sign-compare -fno-asynch > ronous-unwind-tables -fno-delete-null-pointer-checks -O2 -fno-reorder-blocks -fno-ipa-cp-clone -Wframe-larger-than=2048 -fstack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -DKBUILD_BASENAME='"main"' -DKBUILD_MODNAME='"main"' -c -o init/.tmp_main.o init/main.c Command line looks fine: -fstack-protector is present. > arch/x86/Makefile:133: stack-protector enabled but compiler support broken Well that confirms what I was suspecting: the stack protector support in your compiler is broken. :) This is the result of the check done in scripts/gcc-x86_64-has-stack-protector.sh: echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs" if [ "$?" -eq "0" ] ; then echo y else echo n fi where $* is from arch/x86/Makefile: ifdef CONFIG_CC_STACKPROTECTOR cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh ifneq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) $(warning stack-protector enabled but compiler support broken) endif endif > arch/x86/Makefile:148: CONFIG_X86_X32 enabled but no binutils support > Makefile:687: Cannot use CONFIG_KCOV: -fsanitize-coverage=trace-pc is not supported by compiler > Makefile:1041: "Cannot use CONFIG_STACK_VALIDATION, please install libelf-dev or elfutils-libelf-devel" > > We still have -fstack-protector but at least we got a build-time warning > this time. > > akpm3:/usr/src/25> nm init/main.o | grep chk > U __stack_chk_fail > U __stack_chk_guard > > The build system should be handling this automatically - we shouldn't > be failing the build and then requiring the user to go fiddle Kconfig. Well... so, this is a similar problem to what I faced when adding -fstack-protector-strong. I haven't found a way to reject a config that isn't supported by the compiler without breaking the ability to load the config at all. As such, the best that seems to be able to be done is to emit a warning about WHY your build is about to fail, and then letting the build fail. It's not acceptable to just silently disable the CONFIG, as I outlined in the CC_STACKPROTECTOR Makefile section: # Additionally, we don't want to fallback and/or silently change which compiler # flags will be used, since that leads to producing kernels with different # security feature characteristics depending on the compiler used. ("But I # selected CC_STACKPROTECTOR_STRONG! Why did it build with _REGULAR?!") # # The middle ground is to warn here so that the failed option is obvious, but # to let the build fail with bad compiler flags so that we can't produce a # kernel when there is a CONFIG and compiler mismatch. In this case, it's that your gcc-4.4.4 is producing a broken stack protector, and the best the kernel can do is tell you it's broken and let the build fail. (Did your gcc-4.4.4 ever build with CONFIG_CC_STACKPROTECTOR enabled?) -Kees -- Kees Cook Chrome OS & Brillo Security -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href