Loading arch/x86/Kconfig +10 −13 Original line number Diff line number Diff line Loading @@ -1340,13 +1340,17 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. config CC_STACKPROTECTOR_ALL bool config CC_STACKPROTECTOR bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" depends on X86_64 && EXPERIMENTAL && BROKEN depends on X86_64 select CC_STACKPROTECTOR_ALL help This option turns on the -fstack-protector GCC feature. This feature puts, at the beginning of critical functions, a canary value on the stack just before the return address, and validates 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 Loading @@ -1354,15 +1358,8 @@ config CC_STACKPROTECTOR 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. config CC_STACKPROTECTOR_ALL bool "Use stack-protector for all functions" depends on CC_STACKPROTECTOR help Normally, GCC only inserts the canary value protection for functions that use large-ish on-stack buffers. By enabling this option, GCC will be asked to do this for ALL functions. detected and for those versions, this configuration option is ignored. (and a warning is printed during bootup) source kernel/Kconfig.hz Loading arch/x86/Kconfig.debug +1 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ config DEBUG_RODATA config DEBUG_RODATA_TEST bool "Testcase for the DEBUG_RODATA feature" depends on DEBUG_RODATA default y help This option enables a testcase for the DEBUG_RODATA feature as well as for the change_page_attr() infrastructure. Loading arch/x86/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ else stackp := $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh stackp-$(CONFIG_CC_STACKPROTECTOR) := $(shell $(stackp) \ "$(CC)" -fstack-protector ) "$(CC)" "-fstack-protector -DGCC_HAS_SP" ) stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(stackp) \ "$(CC)" -fstack-protector-all ) Loading arch/x86/include/asm/pda.h +2 −2 Original line number Diff line number Diff line Loading @@ -17,11 +17,9 @@ struct x8664_pda { unsigned long unused4; int unused5; unsigned int unused6; /* 36 was cpunumber */ #ifdef CONFIG_CC_STACKPROTECTOR unsigned long stack_canary; /* 40 stack canary value */ /* gcc-ABI: this canary MUST be at offset 40!!! */ #endif short in_bootmem; /* pda lives in bootmem */ } ____cacheline_aligned_in_smp; Loading @@ -42,4 +40,6 @@ extern void pda_init(int); #endif #define refresh_stack_canary() write_pda(stack_canary, current->stack_canary) #endif /* _ASM_X86_PDA_H */ arch/x86/include/asm/stackprotector.h 0 → 100644 +39 −0 Original line number Diff line number Diff line #ifndef _ASM_STACKPROTECTOR_H #define _ASM_STACKPROTECTOR_H 1 #include <asm/tsc.h> #include <asm/pda.h> /* * Initialize the stackprotector canary value. * * NOTE: this must only be called from functions that never return, * and it must always be inlined. */ static __always_inline void boot_init_stack_canary(void) { u64 canary; u64 tsc; /* * If we're the non-boot CPU, nothing set the PDA stack * canary up for us - and if we are the boot CPU we have * a 0 stack canary. This is a good place for updating * it, as we wont ever return from this function (so the * invalid canaries already on the stack wont ever * trigger). * * We both use the random pool and the current TSC as a source * of randomness. The TSC only matters for very early init, * there it already has some randomness on most systems. Later * on during the bootup the random pool has true entropy too. */ get_random_bytes(&canary, sizeof(canary)); tsc = __native_read_tsc(); canary += tsc + (tsc << 32UL); current->stack_canary = canary; write_pda(stack_canary, canary); } #endif Loading
arch/x86/Kconfig +10 −13 Original line number Diff line number Diff line Loading @@ -1340,13 +1340,17 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. config CC_STACKPROTECTOR_ALL bool config CC_STACKPROTECTOR bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" depends on X86_64 && EXPERIMENTAL && BROKEN depends on X86_64 select CC_STACKPROTECTOR_ALL help This option turns on the -fstack-protector GCC feature. This feature puts, at the beginning of critical functions, a canary value on the stack just before the return address, and validates 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 Loading @@ -1354,15 +1358,8 @@ config CC_STACKPROTECTOR 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. config CC_STACKPROTECTOR_ALL bool "Use stack-protector for all functions" depends on CC_STACKPROTECTOR help Normally, GCC only inserts the canary value protection for functions that use large-ish on-stack buffers. By enabling this option, GCC will be asked to do this for ALL functions. detected and for those versions, this configuration option is ignored. (and a warning is printed during bootup) source kernel/Kconfig.hz Loading
arch/x86/Kconfig.debug +1 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ config DEBUG_RODATA config DEBUG_RODATA_TEST bool "Testcase for the DEBUG_RODATA feature" depends on DEBUG_RODATA default y help This option enables a testcase for the DEBUG_RODATA feature as well as for the change_page_attr() infrastructure. Loading
arch/x86/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ else stackp := $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh stackp-$(CONFIG_CC_STACKPROTECTOR) := $(shell $(stackp) \ "$(CC)" -fstack-protector ) "$(CC)" "-fstack-protector -DGCC_HAS_SP" ) stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(stackp) \ "$(CC)" -fstack-protector-all ) Loading
arch/x86/include/asm/pda.h +2 −2 Original line number Diff line number Diff line Loading @@ -17,11 +17,9 @@ struct x8664_pda { unsigned long unused4; int unused5; unsigned int unused6; /* 36 was cpunumber */ #ifdef CONFIG_CC_STACKPROTECTOR unsigned long stack_canary; /* 40 stack canary value */ /* gcc-ABI: this canary MUST be at offset 40!!! */ #endif short in_bootmem; /* pda lives in bootmem */ } ____cacheline_aligned_in_smp; Loading @@ -42,4 +40,6 @@ extern void pda_init(int); #endif #define refresh_stack_canary() write_pda(stack_canary, current->stack_canary) #endif /* _ASM_X86_PDA_H */
arch/x86/include/asm/stackprotector.h 0 → 100644 +39 −0 Original line number Diff line number Diff line #ifndef _ASM_STACKPROTECTOR_H #define _ASM_STACKPROTECTOR_H 1 #include <asm/tsc.h> #include <asm/pda.h> /* * Initialize the stackprotector canary value. * * NOTE: this must only be called from functions that never return, * and it must always be inlined. */ static __always_inline void boot_init_stack_canary(void) { u64 canary; u64 tsc; /* * If we're the non-boot CPU, nothing set the PDA stack * canary up for us - and if we are the boot CPU we have * a 0 stack canary. This is a good place for updating * it, as we wont ever return from this function (so the * invalid canaries already on the stack wont ever * trigger). * * We both use the random pool and the current TSC as a source * of randomness. The TSC only matters for very early init, * there it already has some randomness on most systems. Later * on during the bootup the random pool has true entropy too. */ get_random_bytes(&canary, sizeof(canary)); tsc = __native_read_tsc(); canary += tsc + (tsc << 32UL); current->stack_canary = canary; write_pda(stack_canary, canary); } #endif