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:
Коммит
ad3ab302fd
20
Makefile
20
Makefile
|
@ -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)
|
||||||
|
|
67
arch/Kconfig
67
arch/Kconfig
|
@ -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
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче