Merge branch 'core-stackprotector-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull strong stackprotector support from Ingo Molnar:
 "This tree adds a CONFIG_CC_STACKPROTECTOR_STRONG=y, a new, stronger
  stack canary checking method supported by the newest GCC versions (4.9
  and later).

  Here's the 'intensity comparison' between the various protection
  modes:

      - defconfig
        11430641 kernel text size
        36110 function bodies

      - defconfig + CONFIG_CC_STACKPROTECTOR_REGULAR
        11468490 kernel text size (+0.33%)
        1015 of 36110 functions are stack-protected (2.81%)

      - defconfig + CONFIG_CC_STACKPROTECTOR_STRONG via this patch
        11692790 kernel text size (+2.24%)
        7401 of 36110 functions are stack-protected (20.5%)

  the strong model comes with non-trivial costs, which is why we
  preserved the 'regular' and 'none' models as well"

* 'core-stackprotector-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  stackprotector: Introduce CONFIG_CC_STACKPROTECTOR_STRONG
  stackprotector: Unify the HAVE_CC_STACKPROTECTOR logic between architectures
This commit is contained in:
Linus Torvalds 2014-01-20 10:26:31 -08:00
Родитель a693c46e14 8779657d29
Коммит ad3ab302fd
11 изменённых файлов: 105 добавлений и 75 удалений

Просмотреть файл

@ -595,10 +595,24 @@ ifneq ($(CONFIG_FRAME_WARN),0)
KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN})
endif endif
# Force gcc to behave correct even for buggy distributions # Handle stack protector mode.
ifndef CONFIG_CC_STACKPROTECTOR ifdef CONFIG_CC_STACKPROTECTOR_REGULAR
KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) stackp-flag := -fstack-protector
ifeq ($(call cc-option, $(stackp-flag)),)
$(warning Cannot use CONFIG_CC_STACKPROTECTOR: \
-fstack-protector not supported by compiler))
endif
else ifdef CONFIG_CC_STACKPROTECTOR_STRONG
stackp-flag := -fstack-protector-strong
ifeq ($(call cc-option, $(stackp-flag)),)
$(warning Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \
-fstack-protector-strong not supported by compiler)
endif
else
# Force off for distro compilers that enable stack protector by default.
stackp-flag := $(call cc-option, -fno-stack-protector)
endif endif
KBUILD_CFLAGS += $(stackp-flag)
# This warning generated too much noise in a regular build. # This warning generated too much noise in a regular build.
# Use make W=1 to enable this warning (see scripts/Makefile.build) # Use make W=1 to enable this warning (see scripts/Makefile.build)

Просмотреть файл

@ -336,6 +336,73 @@ config SECCOMP_FILTER
See Documentation/prctl/seccomp_filter.txt for details. See Documentation/prctl/seccomp_filter.txt for details.
config HAVE_CC_STACKPROTECTOR
bool
help
An arch should select this symbol if:
- its compiler supports the -fstack-protector option
- it has implemented a stack canary (e.g. __stack_chk_guard)
config CC_STACKPROTECTOR
def_bool n
help
Set when a stack-protector mode is enabled, so that the build
can enable kernel-side support for the GCC feature.
choice
prompt "Stack Protector buffer overflow detection"
depends on HAVE_CC_STACKPROTECTOR
default CC_STACKPROTECTOR_NONE
help
This option turns on the "stack-protector" GCC feature. This
feature puts, at the beginning of functions, a canary value on
the stack just before the return address, and validates
the value just before actually returning. Stack based buffer
overflows (that need to overwrite this return address) now also
overwrite the canary, which gets detected and the attack is then
neutralized via a kernel panic.
config CC_STACKPROTECTOR_NONE
bool "None"
help
Disable "stack-protector" GCC feature.
config CC_STACKPROTECTOR_REGULAR
bool "Regular"
select CC_STACKPROTECTOR
help
Functions will have the stack-protector canary logic added if they
have an 8-byte or larger character array on the stack.
This feature requires gcc version 4.2 or above, or a distribution
gcc with the feature backported ("-fstack-protector").
On an x86 "defconfig" build, this feature adds canary checks to
about 3% of all kernel functions, which increases kernel code size
by about 0.3%.
config CC_STACKPROTECTOR_STRONG
bool "Strong"
select CC_STACKPROTECTOR
help
Functions will have the stack-protector canary logic added in any
of the following conditions:
- local variable's address used as part of the right hand side of an
assignment or function argument
- local variable is an array (or union containing an array),
regardless of array type or length
- uses register local variables
This feature requires gcc version 4.9 or above, or a distribution
gcc with the feature backported ("-fstack-protector-strong").
On an x86 "defconfig" build, this feature adds canary checks to
about 20% of all kernel functions, which increases the kernel code
size by about 2%.
endchoice
config HAVE_CONTEXT_TRACKING config HAVE_CONTEXT_TRACKING
bool bool
help help

Просмотреть файл

@ -30,6 +30,7 @@ config ARM
select HAVE_BPF_JIT select HAVE_BPF_JIT
select HAVE_CONTEXT_TRACKING select HAVE_CONTEXT_TRACKING
select HAVE_C_RECORDMCOUNT select HAVE_C_RECORDMCOUNT
select HAVE_CC_STACKPROTECTOR
select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_API_DEBUG select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS select HAVE_DMA_ATTRS
@ -1856,18 +1857,6 @@ config SECCOMP
and the task is only allowed to execute a few safe syscalls and the task is only allowed to execute a few safe syscalls
defined by each seccomp mode. defined by each seccomp mode.
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
help
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of functions, a canary value on
the stack just before the return address, and validates
the value just before actually returning. Stack based buffer
overflows (that need to overwrite this return address) now also
overwrite the canary, which gets detected and the attack is then
neutralized via a kernel panic.
This feature requires gcc version 4.2 or above.
config SWIOTLB config SWIOTLB
def_bool y def_bool y

Просмотреть файл

@ -40,10 +40,6 @@ ifeq ($(CONFIG_FRAME_POINTER),y)
KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
endif endif
ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
KBUILD_CFLAGS +=-fstack-protector
endif
ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
KBUILD_CPPFLAGS += -mbig-endian KBUILD_CPPFLAGS += -mbig-endian
AS += -EB AS += -EB

Просмотреть файл

@ -127,6 +127,18 @@ asmlinkage void __div0(void)
error("Attempting division by 0!"); error("Attempting division by 0!");
} }
unsigned long __stack_chk_guard;
void __stack_chk_guard_setup(void)
{
__stack_chk_guard = 0x000a0dff;
}
void __stack_chk_fail(void)
{
error("stack-protector: Kernel stack is corrupted\n");
}
extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
@ -137,6 +149,8 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
{ {
int ret; int ret;
__stack_chk_guard_setup();
output_data = (unsigned char *)output_start; output_data = (unsigned char *)output_start;
free_mem_ptr = free_mem_ptr_p; free_mem_ptr = free_mem_ptr_p;
free_mem_end_ptr = free_mem_ptr_end_p; free_mem_end_ptr = free_mem_ptr_end_p;

Просмотреть файл

@ -47,6 +47,7 @@ config MIPS
select MODULES_USE_ELF_RELA if MODULES && 64BIT select MODULES_USE_ELF_RELA if MODULES && 64BIT
select CLONE_BACKWARDS select CLONE_BACKWARDS
select HAVE_DEBUG_STACKOVERFLOW select HAVE_DEBUG_STACKOVERFLOW
select HAVE_CC_STACKPROTECTOR
menu "Machine selection" menu "Machine selection"
@ -2322,19 +2323,6 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here. If unsure, say Y. Only embedded should say N here.
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
help
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of functions, a canary value on
the stack just before the return address, and validates
the value just before actually returning. Stack based buffer
overflows (that need to overwrite this return address) now also
overwrite the canary, which gets detected and the attack is then
neutralized via a kernel panic.
This feature requires gcc version 4.2 or above.
config USE_OF config USE_OF
bool bool
select OF select OF

Просмотреть файл

@ -232,10 +232,6 @@ bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \
LDFLAGS += -m $(ld-emul) LDFLAGS += -m $(ld-emul)
ifdef CONFIG_CC_STACKPROTECTOR
KBUILD_CFLAGS += -fstack-protector
endif
ifdef CONFIG_MIPS ifdef CONFIG_MIPS
CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \

Просмотреть файл

@ -66,6 +66,7 @@ config SUPERH32
select PERF_EVENTS select PERF_EVENTS
select ARCH_HIBERNATION_POSSIBLE if MMU select ARCH_HIBERNATION_POSSIBLE if MMU
select SPARSE_IRQ select SPARSE_IRQ
select HAVE_CC_STACKPROTECTOR
config SUPERH64 config SUPERH64
def_bool ARCH = "sh64" def_bool ARCH = "sh64"
@ -695,20 +696,6 @@ config SECCOMP
If unsure, say N. If unsure, say N.
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
depends on SUPERH32
help
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of functions, a canary value on
the stack just before the return address, and validates
the value just before actually returning. Stack based buffer
overflows (that need to overwrite this return address) now also
overwrite the canary, which gets detected and the attack is then
neutralized via a kernel panic.
This feature requires gcc version 4.2 or above.
config SMP config SMP
bool "Symmetric multi-processing support" bool "Symmetric multi-processing support"
depends on SYS_SUPPORTS_SMP depends on SYS_SUPPORTS_SMP

Просмотреть файл

@ -199,10 +199,6 @@ ifeq ($(CONFIG_DWARF_UNWINDER),y)
KBUILD_CFLAGS += -fasynchronous-unwind-tables KBUILD_CFLAGS += -fasynchronous-unwind-tables
endif endif
ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
KBUILD_CFLAGS += -fstack-protector
endif
libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)

Просмотреть файл

@ -125,6 +125,7 @@ config X86
select RTC_LIB select RTC_LIB
select HAVE_DEBUG_STACKOVERFLOW select HAVE_DEBUG_STACKOVERFLOW
select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64
select HAVE_CC_STACKPROTECTOR
config INSTRUCTION_DECODER config INSTRUCTION_DECODER
def_bool y def_bool y
@ -1617,22 +1618,6 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here. If unsure, say Y. Only embedded should say N here.
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection"
---help---
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of functions, a canary value on
the stack just before the return address, and validates
the value just before actually returning. Stack based buffer
overflows (that need to overwrite this return address) now also
overwrite the canary, which gets detected and the attack is then
neutralized via a kernel panic.
This feature requires gcc version 4.2 or above, or a distribution
gcc with the feature backported. Older versions are automatically
detected and for those versions, this configuration option is
ignored. (and a warning is printed during bootup)
source kernel/Kconfig.hz source kernel/Kconfig.hz
config KEXEC config KEXEC

Просмотреть файл

@ -89,13 +89,11 @@ else
KBUILD_CFLAGS += -maccumulate-outgoing-args KBUILD_CFLAGS += -maccumulate-outgoing-args
endif endif
# Make sure compiler does not have buggy stack-protector support.
ifdef CONFIG_CC_STACKPROTECTOR ifdef CONFIG_CC_STACKPROTECTOR
cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) ifneq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
stackp-y := -fstack-protector $(warning stack-protector enabled but compiler support broken)
KBUILD_CFLAGS += $(stackp-y)
else
$(warning stack protector enabled but no compiler support)
endif endif
endif endif