Re: [PATCH v6 20/27] x86: Support global stack cookie
On Fri, Feb 1, 2019 at 2:36 PM Andy Lutomirski wrote: > > > > On Feb 1, 2019, at 12:21 PM, Thomas Garnier wrote: > > > >> On Fri, Feb 1, 2019 at 11:27 AM Andy Lutomirski wrote: > >> > >>> On Thu, Jan 31, 2019 at 11:29 AM Thomas Garnier > >>> wrote: > >>> > >>> Add an off-by-default configuration option to use a global stack cookie > >>> instead of the default TLS. This configuration option will only be used > >>> with PIE binaries. > >>> > >>> For kernel stack cookie, the compiler uses the mcmodel=kernel to switch > >>> between the fs segment to gs segment. A PIE binary does not use > >>> mcmodel=kernel because it can be relocated anywhere, therefore the > >>> compiler will default to the fs segment register. This is fixed on the > >>> latest version of gcc. > >> > >> I hate all these gcc-sucks-so-we-hack-it-and-change-nasty-semantics > >> options. How about just preventing use of both stack protector and > >> PIE unless the version of gcc in use is new enough. > > > > So fail the build in this scenario? > > Fail the build or use some Kconfig magic to prevent this from being > configured in the first place. Ok, I can do that in next iteration. > > > > >> > >> Also, does -mstack-protector-guard-reg not solve this? See > >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708. Or is there > >> another bug? Or are you worried about gcc versions that don't have > >> that feature yet? > > > > I am worried about gcc versions that don't have this feature, yes.
Re: [PATCH v6 20/27] x86: Support global stack cookie
> On Feb 1, 2019, at 12:21 PM, Thomas Garnier wrote: > >> On Fri, Feb 1, 2019 at 11:27 AM Andy Lutomirski wrote: >> >>> On Thu, Jan 31, 2019 at 11:29 AM Thomas Garnier >>> wrote: >>> >>> Add an off-by-default configuration option to use a global stack cookie >>> instead of the default TLS. This configuration option will only be used >>> with PIE binaries. >>> >>> For kernel stack cookie, the compiler uses the mcmodel=kernel to switch >>> between the fs segment to gs segment. A PIE binary does not use >>> mcmodel=kernel because it can be relocated anywhere, therefore the >>> compiler will default to the fs segment register. This is fixed on the >>> latest version of gcc. >> >> I hate all these gcc-sucks-so-we-hack-it-and-change-nasty-semantics >> options. How about just preventing use of both stack protector and >> PIE unless the version of gcc in use is new enough. > > So fail the build in this scenario? Fail the build or use some Kconfig magic to prevent this from being configured in the first place. > >> >> Also, does -mstack-protector-guard-reg not solve this? See >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708. Or is there >> another bug? Or are you worried about gcc versions that don't have >> that feature yet? > > I am worried about gcc versions that don't have this feature, yes.
Re: [PATCH v6 20/27] x86: Support global stack cookie
On Fri, Feb 1, 2019 at 11:27 AM Andy Lutomirski wrote: > > On Thu, Jan 31, 2019 at 11:29 AM Thomas Garnier wrote: > > > > Add an off-by-default configuration option to use a global stack cookie > > instead of the default TLS. This configuration option will only be used > > with PIE binaries. > > > > For kernel stack cookie, the compiler uses the mcmodel=kernel to switch > > between the fs segment to gs segment. A PIE binary does not use > > mcmodel=kernel because it can be relocated anywhere, therefore the > > compiler will default to the fs segment register. This is fixed on the > > latest version of gcc. > > I hate all these gcc-sucks-so-we-hack-it-and-change-nasty-semantics > options. How about just preventing use of both stack protector and > PIE unless the version of gcc in use is new enough. So fail the build in this scenario? > > Also, does -mstack-protector-guard-reg not solve this? See > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708. Or is there > another bug? Or are you worried about gcc versions that don't have > that feature yet? I am worried about gcc versions that don't have this feature, yes.
Re: [PATCH v6 20/27] x86: Support global stack cookie
On Thu, Jan 31, 2019 at 11:29 AM Thomas Garnier wrote: > > Add an off-by-default configuration option to use a global stack cookie > instead of the default TLS. This configuration option will only be used > with PIE binaries. > > For kernel stack cookie, the compiler uses the mcmodel=kernel to switch > between the fs segment to gs segment. A PIE binary does not use > mcmodel=kernel because it can be relocated anywhere, therefore the > compiler will default to the fs segment register. This is fixed on the > latest version of gcc. I hate all these gcc-sucks-so-we-hack-it-and-change-nasty-semantics options. How about just preventing use of both stack protector and PIE unless the version of gcc in use is new enough. Also, does -mstack-protector-guard-reg not solve this? See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708. Or is there another bug? Or are you worried about gcc versions that don't have that feature yet?
[PATCH v6 20/27] x86: Support global stack cookie
Add an off-by-default configuration option to use a global stack cookie instead of the default TLS. This configuration option will only be used with PIE binaries. For kernel stack cookie, the compiler uses the mcmodel=kernel to switch between the fs segment to gs segment. A PIE binary does not use mcmodel=kernel because it can be relocated anywhere, therefore the compiler will default to the fs segment register. This is fixed on the latest version of gcc. If the segment selector is available, it will be automatically added. If the automatic configuration was selected, a warning is written and the global variable stack cookie is used. If a specific stack mode was selected (regular or strong) and the compiler does not support selecting the segment register, an error is emitted. Signed-off-by: Thomas Garnier --- arch/x86/Kconfig | 12 arch/x86/Makefile | 9 + arch/x86/entry/entry_32.S | 3 ++- arch/x86/entry/entry_64.S | 3 ++- arch/x86/include/asm/processor.h | 3 ++- arch/x86/include/asm/stackprotector.h | 19 ++- arch/x86/kernel/asm-offsets.c | 3 ++- arch/x86/kernel/asm-offsets_32.c | 3 ++- arch/x86/kernel/asm-offsets_64.c | 3 ++- arch/x86/kernel/cpu/common.c | 3 ++- arch/x86/kernel/head_32.S | 3 ++- arch/x86/kernel/process.c | 5 + 12 files changed, 56 insertions(+), 13 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 0519da6f8ee4..263d81c570b2 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2221,6 +2221,18 @@ config RANDOMIZE_MEMORY_PHYSICAL_PADDING If unsure, leave at the default value. +config X86_GLOBAL_STACKPROTECTOR + bool "Stack cookie using a global variable" + depends on CC_STACKPROTECTOR_AUTO + default n + help + This option turns on the "stack-protector" GCC feature using a global + variable instead of a segment register. It is useful when the + compiler does not support custom segment registers when building a + position independent (PIE) binary. + + If unsure, say N + config HOTPLUG_CPU bool "Support for hot-pluggable CPUs" depends on SMP diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 76bc4dc03d5e..65d6d9a1dd22 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -132,6 +132,15 @@ else KBUILD_CFLAGS += -mcmodel=kernel endif +ifdef CONFIG_X86_GLOBAL_STACKPROTECTOR +ifeq ($(call cc-option, -mstack-protector-guard=global),) +$(error Cannot use CONFIG_X86_GLOBAL_STACKPROTECTOR: \ +-mstack-protector-guard=global not supported \ +by compiler) +endif +KBUILD_CFLAGS += -mstack-protector-guard=global +endif + ifdef CONFIG_X86_X32 x32_ld_ok := $(call try-run,\ /bin/echo -e '1: .quad 1b' | \ diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index d309f30cf7af..1a4abb98664b 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -655,7 +655,8 @@ ENTRY(__switch_to_asm) movl%esp, TASK_threadsp(%eax) movlTASK_threadsp(%edx), %esp -#ifdef CONFIG_STACKPROTECTOR +#if defined(CONFIG_STACKPROTECTOR) && \ + !defined(CONFIG_X86_GLOBAL_STACKPROTECTOR) movlTASK_stack_canary(%edx), %ebx movl%ebx, PER_CPU_VAR(stack_canary)+stack_canary_offset #endif diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index fc15fe058d3c..1ae9c85241dc 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -296,7 +296,8 @@ ENTRY(__switch_to_asm) movq%rsp, TASK_threadsp(%rdi) movqTASK_threadsp(%rsi), %rsp -#ifdef CONFIG_STACKPROTECTOR +#if defined(CONFIG_STACKPROTECTOR) && \ + !defined(CONFIG_X86_GLOBAL_STACKPROTECTOR) movqTASK_stack_canary(%rsi), %rbx movq%rbx, PER_CPU_VAR(irq_stack_union + stack_canary_offset) #endif diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 18f1e8269ad7..d322b1789d94 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -416,7 +416,8 @@ extern asmlinkage void ignore_sysret(void); void save_fsgs_for_kvm(void); #endif #else /* X86_64 */ -#ifdef CONFIG_STACKPROTECTOR +#if defined(CONFIG_STACKPROTECTOR) && \ + !defined(CONFIG_X86_GLOBAL_STACKPROTECTOR) /* * Make sure stack canary segment base is cached-aligned: * "For Intel Atom processors, avoid non zero segment base address diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h index 8ec97a62c245..4e120cf36782 100644 --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h @@ -52,6 +52,10 @@ #define GDT_STACK_CANARY_INIT \