* [PATCH v3 1/2] riscv: Add STACKPROTECTOR supported @ 2020-07-10 16:19 guoren 2020-07-10 16:19 ` [PATCH v3 2/2] riscv: Enable per-task stack canaries guoren 0 siblings, 1 reply; 6+ messages in thread From: guoren @ 2020-07-10 16:19 UTC (permalink / raw) To: palmerdabbelt, paul.walmsley, anup, greentime.hu, zong.li, keescook, bjorn.topel, atish.patra, cooper.qu Cc: Albert Ou, linux-kernel, linux-csky, Guo Ren, guoren, Masami Hiramatsu, linux-riscv, Greentime Hu From: Guo Ren <guoren@linux.alibaba.com> The -fstack-protector & -fstack-protector-strong features are from gcc. The patch only add basic kernel support to stack-protector feature and some arch could have its own solution such as ARM64_PTR_AUTH. After enabling STACKPROTECTOR and STACKPROTECTOR_STRONG, the .text size is expanded from 0x7de066 to 0x81fb32 (only 5%) to add canary checking code. Signed-off-by: Guo Ren <guoren@linux.alibaba.com> Reviewed-by: Kees Cook <keescook@chromium.org> Cc: Paul Walmsley <paul.walmsley@sifive.com> Cc: Palmer Dabbelt <palmerdabbelt@google.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Björn Töpel <bjorn.topel@gmail.com> Cc: Greentime Hu <green.hu@gmail.com> Cc: Atish Patra <atish.patra@wdc.com> --- Change v2: - Fixup rsicv32 compile warning Signed-off-by: Guo Ren <guoren@linux.alibaba.com> --- arch/riscv/Kconfig | 1 + arch/riscv/include/asm/stackprotector.h | 33 +++++++++++++++++++++++++++++++++ arch/riscv/kernel/process.c | 6 ++++++ 3 files changed, 40 insertions(+) create mode 100644 arch/riscv/include/asm/stackprotector.h diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index f927a91..4b0e308 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -63,6 +63,7 @@ config RISCV select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_STACKPROTECTOR select HAVE_SYSCALL_TRACEPOINTS select IRQ_DOMAIN select MODULES_USE_ELF_RELA if MODULES diff --git a/arch/riscv/include/asm/stackprotector.h b/arch/riscv/include/asm/stackprotector.h new file mode 100644 index 00000000..d95f7b2 --- /dev/null +++ b/arch/riscv/include/asm/stackprotector.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_RISCV_STACKPROTECTOR_H +#define _ASM_RISCV_STACKPROTECTOR_H + +#include <linux/random.h> +#include <linux/version.h> +#include <asm/timex.h> + +extern unsigned long __stack_chk_guard; + +/* + * 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) +{ + unsigned long canary; + unsigned long tsc; + + /* Try to get a semi random initial value. */ + get_random_bytes(&canary, sizeof(canary)); + tsc = get_cycles(); + canary += tsc + (tsc << BITS_PER_LONG/2); + canary ^= LINUX_VERSION_CODE; + canary &= CANARY_MASK; + + current->stack_canary = canary; + __stack_chk_guard = current->stack_canary; +} +#endif /* _ASM_RISCV_STACKPROTECTOR_H */ diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index 824d117..6548929 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -24,6 +24,12 @@ register unsigned long gp_in_global __asm__("gp"); +#ifdef CONFIG_STACKPROTECTOR +#include <linux/stackprotector.h> +unsigned long __stack_chk_guard __read_mostly; +EXPORT_SYMBOL(__stack_chk_guard); +#endif + extern asmlinkage void ret_from_fork(void); extern asmlinkage void ret_from_kernel_thread(void); -- 2.7.4 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/2] riscv: Enable per-task stack canaries 2020-07-10 16:19 [PATCH v3 1/2] riscv: Add STACKPROTECTOR supported guoren @ 2020-07-10 16:19 ` guoren 2020-07-13 2:39 ` Kees Cook 2020-07-14 21:37 ` Palmer Dabbelt 0 siblings, 2 replies; 6+ messages in thread From: guoren @ 2020-07-10 16:19 UTC (permalink / raw) To: palmerdabbelt, paul.walmsley, anup, greentime.hu, zong.li, keescook, bjorn.topel, atish.patra, cooper.qu Cc: linux-riscv, Guo Ren, guoren, linux-kernel, linux-csky From: Guo Ren <guoren@linux.alibaba.com> This enables the use of per-task stack canary values if GCC has support for emitting the stack canary reference relative to the value of tp, which holds the task struct pointer in the riscv kernel. After compare arm64 and x86 implementations, seems arm64's is more flexible and readable. The key point is how gcc get the offset of stack_canary from gs/el0_sp. x86: Use a fix offset from gs, not flexible. struct fixed_percpu_data { /* * GCC hardcodes the stack canary as %gs:40. Since the * irq_stack is the object at %gs:0, we reserve the bottom * 48 bytes of the irq stack for the canary. */ char gs_base[40]; // :( unsigned long stack_canary; }; arm64: Use -mstack-protector-guard-offset & guard-reg gcc options: -mstack-protector-guard=sysreg -mstack-protector-guard-reg=sp_el0 -mstack-protector-guard-offset=xxx riscv: Use -mstack-protector-guard-offset & guard-reg gcc options: -mstack-protector-guard=tls -mstack-protector-guard-reg=tp -mstack-protector-guard-offset=xxx Here is riscv gcc's work [1]. [1] https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549583.html In the end, these codes are inserted by gcc before return: * 0xffffffe00020b396 <+120>: ld a5,1008(tp) # 0x3f0 * 0xffffffe00020b39a <+124>: xor a5,a5,a4 * 0xffffffe00020b39c <+126>: mv a0,s5 * 0xffffffe00020b39e <+128>: bnez a5,0xffffffe00020b61c <_do_fork+766> 0xffffffe00020b3a2 <+132>: ld ra,136(sp) 0xffffffe00020b3a4 <+134>: ld s0,128(sp) 0xffffffe00020b3a6 <+136>: ld s1,120(sp) 0xffffffe00020b3a8 <+138>: ld s2,112(sp) 0xffffffe00020b3aa <+140>: ld s3,104(sp) 0xffffffe00020b3ac <+142>: ld s4,96(sp) 0xffffffe00020b3ae <+144>: ld s5,88(sp) 0xffffffe00020b3b0 <+146>: ld s6,80(sp) 0xffffffe00020b3b2 <+148>: ld s7,72(sp) 0xffffffe00020b3b4 <+150>: addi sp,sp,144 0xffffffe00020b3b6 <+152>: ret ... * 0xffffffe00020b61c <+766>: auipc ra,0x7f8 * 0xffffffe00020b620 <+770>: jalr -1764(ra) # 0xffffffe000a02f38 <__stack_chk_fail> Signed-off-by: Guo Ren <guoren@linux.alibaba.com> Signed-off-by: cooper <cooper.qu@linux.alibaba.com> Cc: cooper <cooper.qu@linux.alibaba.com> Cc: Kees Cook <keescook@chromium.org> --- Change v2: - Change to -mstack-protector-guard=tls for gcc final define - Solve compile error by changing position of KBUILD_CFLAGS in Makefile Signed-off-by: Guo Ren <guoren@linux.alibaba.com> --- arch/riscv/Kconfig | 7 +++++++ arch/riscv/Makefile | 10 ++++++++++ arch/riscv/include/asm/stackprotector.h | 3 ++- arch/riscv/kernel/asm-offsets.c | 3 +++ arch/riscv/kernel/process.c | 2 +- 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 4b0e308..d98ce29 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -394,6 +394,13 @@ config CMDLINE_FORCE endchoice +config CC_HAVE_STACKPROTECTOR_TLS + def_bool $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=tp -mstack-protector-guard-offset=0) + +config STACKPROTECTOR_PER_TASK + def_bool y + depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_TLS + endmenu config BUILTIN_DTB diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index fb6e37d..f5f8ee9 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -68,6 +68,16 @@ KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) # architectures. It's faster to have GCC emit only aligned accesses. KBUILD_CFLAGS += $(call cc-option,-mstrict-align) +ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) +prepare: stack_protector_prepare +stack_protector_prepare: prepare0 + $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls \ + -mstack-protector-guard-reg=tp \ + -mstack-protector-guard-offset=$(shell \ + awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \ + include/generated/asm-offsets.h)) +endif + # arch specific predefines for sparse CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS) diff --git a/arch/riscv/include/asm/stackprotector.h b/arch/riscv/include/asm/stackprotector.h index d95f7b2..a895e07 100644 --- a/arch/riscv/include/asm/stackprotector.h +++ b/arch/riscv/include/asm/stackprotector.h @@ -28,6 +28,7 @@ static __always_inline void boot_init_stack_canary(void) canary &= CANARY_MASK; current->stack_canary = canary; - __stack_chk_guard = current->stack_canary; + if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK)) + __stack_chk_guard = current->stack_canary; } #endif /* _ASM_RISCV_STACKPROTECTOR_H */ diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c index 07cb9c1..999b465 100644 --- a/arch/riscv/kernel/asm-offsets.c +++ b/arch/riscv/kernel/asm-offsets.c @@ -29,6 +29,9 @@ void asm_offsets(void) OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]); OFFSET(TASK_THREAD_SP, task_struct, thread.sp); OFFSET(TASK_STACK, task_struct, stack); +#ifdef CONFIG_STACKPROTECTOR + OFFSET(TSK_STACK_CANARY, task_struct, stack_canary); +#endif OFFSET(TASK_TI, task_struct, thread_info); OFFSET(TASK_TI_FLAGS, task_struct, thread_info.flags); OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count); diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index 6548929..cb4ac65 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -24,7 +24,7 @@ register unsigned long gp_in_global __asm__("gp"); -#ifdef CONFIG_STACKPROTECTOR +#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) #include <linux/stackprotector.h> unsigned long __stack_chk_guard __read_mostly; EXPORT_SYMBOL(__stack_chk_guard); -- 2.7.4 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] riscv: Enable per-task stack canaries 2020-07-10 16:19 ` [PATCH v3 2/2] riscv: Enable per-task stack canaries guoren @ 2020-07-13 2:39 ` Kees Cook 2020-07-13 4:05 ` Guo Ren 2020-07-14 21:37 ` Palmer Dabbelt 1 sibling, 1 reply; 6+ messages in thread From: Kees Cook @ 2020-07-13 2:39 UTC (permalink / raw) To: guoren Cc: Guo Ren, anup, palmerdabbelt, linux-kernel, linux-csky, paul.walmsley, atish.patra, zong.li, bjorn.topel, cooper.qu, greentime.hu, linux-riscv On Fri, Jul 10, 2020 at 04:19:58PM +0000, guoren@kernel.org wrote: > From: Guo Ren <guoren@linux.alibaba.com> > > This enables the use of per-task stack canary values if GCC has > support for emitting the stack canary reference relative to the > value of tp, which holds the task struct pointer in the riscv > kernel. > > After compare arm64 and x86 implementations, seems arm64's is more > flexible and readable. The key point is how gcc get the offset of > stack_canary from gs/el0_sp. > > x86: Use a fix offset from gs, not flexible. > > struct fixed_percpu_data { > /* > * GCC hardcodes the stack canary as %gs:40. Since the > * irq_stack is the object at %gs:0, we reserve the bottom > * 48 bytes of the irq stack for the canary. > */ > char gs_base[40]; // :( > unsigned long stack_canary; > }; > > arm64: Use -mstack-protector-guard-offset & guard-reg > gcc options: > -mstack-protector-guard=sysreg > -mstack-protector-guard-reg=sp_el0 > -mstack-protector-guard-offset=xxx > > riscv: Use -mstack-protector-guard-offset & guard-reg > gcc options: > -mstack-protector-guard=tls > -mstack-protector-guard-reg=tp > -mstack-protector-guard-offset=xxx > > Here is riscv gcc's work [1]. > > [1] https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549583.html > > In the end, these codes are inserted by gcc before return: > > * 0xffffffe00020b396 <+120>: ld a5,1008(tp) # 0x3f0 > * 0xffffffe00020b39a <+124>: xor a5,a5,a4 > * 0xffffffe00020b39c <+126>: mv a0,s5 > * 0xffffffe00020b39e <+128>: bnez a5,0xffffffe00020b61c <_do_fork+766> > 0xffffffe00020b3a2 <+132>: ld ra,136(sp) > 0xffffffe00020b3a4 <+134>: ld s0,128(sp) > 0xffffffe00020b3a6 <+136>: ld s1,120(sp) > 0xffffffe00020b3a8 <+138>: ld s2,112(sp) > 0xffffffe00020b3aa <+140>: ld s3,104(sp) > 0xffffffe00020b3ac <+142>: ld s4,96(sp) > 0xffffffe00020b3ae <+144>: ld s5,88(sp) > 0xffffffe00020b3b0 <+146>: ld s6,80(sp) > 0xffffffe00020b3b2 <+148>: ld s7,72(sp) > 0xffffffe00020b3b4 <+150>: addi sp,sp,144 > 0xffffffe00020b3b6 <+152>: ret > ... > * 0xffffffe00020b61c <+766>: auipc ra,0x7f8 > * 0xffffffe00020b620 <+770>: jalr -1764(ra) # 0xffffffe000a02f38 <__stack_chk_fail> > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > Signed-off-by: cooper <cooper.qu@linux.alibaba.com> > Cc: cooper <cooper.qu@linux.alibaba.com> > Cc: Kees Cook <keescook@chromium.org> > --- > Change v2: > - Change to -mstack-protector-guard=tls for gcc final define > - Solve compile error by changing position of KBUILD_CFLAGS in > Makefile > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > --- > arch/riscv/Kconfig | 7 +++++++ > arch/riscv/Makefile | 10 ++++++++++ > arch/riscv/include/asm/stackprotector.h | 3 ++- > arch/riscv/kernel/asm-offsets.c | 3 +++ > arch/riscv/kernel/process.c | 2 +- > 5 files changed, 23 insertions(+), 2 deletions(-) > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > index 4b0e308..d98ce29 100644 > --- a/arch/riscv/Kconfig > +++ b/arch/riscv/Kconfig > @@ -394,6 +394,13 @@ config CMDLINE_FORCE > > endchoice > > +config CC_HAVE_STACKPROTECTOR_TLS > + def_bool $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=tp -mstack-protector-guard-offset=0) > + > +config STACKPROTECTOR_PER_TASK > + def_bool y > + depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_TLS > + > endmenu > > config BUILTIN_DTB > diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile > index fb6e37d..f5f8ee9 100644 > --- a/arch/riscv/Makefile > +++ b/arch/riscv/Makefile > @@ -68,6 +68,16 @@ KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) > # architectures. It's faster to have GCC emit only aligned accesses. > KBUILD_CFLAGS += $(call cc-option,-mstrict-align) > > +ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) > +prepare: stack_protector_prepare > +stack_protector_prepare: prepare0 > + $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls \ > + -mstack-protector-guard-reg=tp \ > + -mstack-protector-guard-offset=$(shell \ > + awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \ > + include/generated/asm-offsets.h)) > +endif > + > # arch specific predefines for sparse > CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS) > > diff --git a/arch/riscv/include/asm/stackprotector.h b/arch/riscv/include/asm/stackprotector.h > index d95f7b2..a895e07 100644 > --- a/arch/riscv/include/asm/stackprotector.h > +++ b/arch/riscv/include/asm/stackprotector.h > @@ -28,6 +28,7 @@ static __always_inline void boot_init_stack_canary(void) > canary &= CANARY_MASK; > > current->stack_canary = canary; > - __stack_chk_guard = current->stack_canary; > + if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK)) > + __stack_chk_guard = current->stack_canary; > } > #endif /* _ASM_RISCV_STACKPROTECTOR_H */ > diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c > index 07cb9c1..999b465 100644 > --- a/arch/riscv/kernel/asm-offsets.c > +++ b/arch/riscv/kernel/asm-offsets.c > @@ -29,6 +29,9 @@ void asm_offsets(void) > OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]); > OFFSET(TASK_THREAD_SP, task_struct, thread.sp); > OFFSET(TASK_STACK, task_struct, stack); > +#ifdef CONFIG_STACKPROTECTOR Should this be CONFIG_STACKPROTECTOR_PER_TASK ? > + OFFSET(TSK_STACK_CANARY, task_struct, stack_canary); > +#endif > OFFSET(TASK_TI, task_struct, thread_info); > OFFSET(TASK_TI_FLAGS, task_struct, thread_info.flags); > OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count); > diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c > index 6548929..cb4ac65 100644 > --- a/arch/riscv/kernel/process.c > +++ b/arch/riscv/kernel/process.c > @@ -24,7 +24,7 @@ > > register unsigned long gp_in_global __asm__("gp"); > > -#ifdef CONFIG_STACKPROTECTOR > +#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) > #include <linux/stackprotector.h> > unsigned long __stack_chk_guard __read_mostly; > EXPORT_SYMBOL(__stack_chk_guard); > -- > 2.7.4 > -- Kees Cook _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] riscv: Enable per-task stack canaries 2020-07-13 2:39 ` Kees Cook @ 2020-07-13 4:05 ` Guo Ren 0 siblings, 0 replies; 6+ messages in thread From: Guo Ren @ 2020-07-13 4:05 UTC (permalink / raw) To: Kees Cook Cc: Guo Ren, Anup Patel, Palmer Dabbelt, Linux Kernel Mailing List, linux-csky, Paul Walmsley, Atish Patra, Zong Li, Björn Töpel, cooper.qu, Greentime Hu, linux-riscv Hi Kees, On Mon, Jul 13, 2020 at 10:40 AM Kees Cook <keescook@chromium.org> wrote: > > On Fri, Jul 10, 2020 at 04:19:58PM +0000, guoren@kernel.org wrote: > > From: Guo Ren <guoren@linux.alibaba.com> > > > > This enables the use of per-task stack canary values if GCC has > > support for emitting the stack canary reference relative to the > > value of tp, which holds the task struct pointer in the riscv > > kernel. > > > > After compare arm64 and x86 implementations, seems arm64's is more > > flexible and readable. The key point is how gcc get the offset of > > stack_canary from gs/el0_sp. > > > > x86: Use a fix offset from gs, not flexible. > > > > struct fixed_percpu_data { > > /* > > * GCC hardcodes the stack canary as %gs:40. Since the > > * irq_stack is the object at %gs:0, we reserve the bottom > > * 48 bytes of the irq stack for the canary. > > */ > > char gs_base[40]; // :( > > unsigned long stack_canary; > > }; > > > > arm64: Use -mstack-protector-guard-offset & guard-reg > > gcc options: > > -mstack-protector-guard=sysreg > > -mstack-protector-guard-reg=sp_el0 > > -mstack-protector-guard-offset=xxx > > > > riscv: Use -mstack-protector-guard-offset & guard-reg > > gcc options: > > -mstack-protector-guard=tls > > -mstack-protector-guard-reg=tp > > -mstack-protector-guard-offset=xxx > > > > Here is riscv gcc's work [1]. > > > > [1] https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549583.html > > > > In the end, these codes are inserted by gcc before return: > > > > * 0xffffffe00020b396 <+120>: ld a5,1008(tp) # 0x3f0 > > * 0xffffffe00020b39a <+124>: xor a5,a5,a4 > > * 0xffffffe00020b39c <+126>: mv a0,s5 > > * 0xffffffe00020b39e <+128>: bnez a5,0xffffffe00020b61c <_do_fork+766> > > 0xffffffe00020b3a2 <+132>: ld ra,136(sp) > > 0xffffffe00020b3a4 <+134>: ld s0,128(sp) > > 0xffffffe00020b3a6 <+136>: ld s1,120(sp) > > 0xffffffe00020b3a8 <+138>: ld s2,112(sp) > > 0xffffffe00020b3aa <+140>: ld s3,104(sp) > > 0xffffffe00020b3ac <+142>: ld s4,96(sp) > > 0xffffffe00020b3ae <+144>: ld s5,88(sp) > > 0xffffffe00020b3b0 <+146>: ld s6,80(sp) > > 0xffffffe00020b3b2 <+148>: ld s7,72(sp) > > 0xffffffe00020b3b4 <+150>: addi sp,sp,144 > > 0xffffffe00020b3b6 <+152>: ret > > ... > > * 0xffffffe00020b61c <+766>: auipc ra,0x7f8 > > * 0xffffffe00020b620 <+770>: jalr -1764(ra) # 0xffffffe000a02f38 <__stack_chk_fail> > > > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > > Signed-off-by: cooper <cooper.qu@linux.alibaba.com> > > Cc: cooper <cooper.qu@linux.alibaba.com> > > Cc: Kees Cook <keescook@chromium.org> > > --- > > Change v2: > > - Change to -mstack-protector-guard=tls for gcc final define > > - Solve compile error by changing position of KBUILD_CFLAGS in > > Makefile > > > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > > --- > > arch/riscv/Kconfig | 7 +++++++ > > arch/riscv/Makefile | 10 ++++++++++ > > arch/riscv/include/asm/stackprotector.h | 3 ++- > > arch/riscv/kernel/asm-offsets.c | 3 +++ > > arch/riscv/kernel/process.c | 2 +- > > 5 files changed, 23 insertions(+), 2 deletions(-) > > > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > > index 4b0e308..d98ce29 100644 > > --- a/arch/riscv/Kconfig > > +++ b/arch/riscv/Kconfig > > @@ -394,6 +394,13 @@ config CMDLINE_FORCE > > > > endchoice > > > > +config CC_HAVE_STACKPROTECTOR_TLS > > + def_bool $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=tp -mstack-protector-guard-offset=0) > > + > > +config STACKPROTECTOR_PER_TASK > > + def_bool y > > + depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_TLS > > + > > endmenu > > > > config BUILTIN_DTB > > diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile > > index fb6e37d..f5f8ee9 100644 > > --- a/arch/riscv/Makefile > > +++ b/arch/riscv/Makefile > > @@ -68,6 +68,16 @@ KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) > > # architectures. It's faster to have GCC emit only aligned accesses. > > KBUILD_CFLAGS += $(call cc-option,-mstrict-align) > > > > +ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) > > +prepare: stack_protector_prepare > > +stack_protector_prepare: prepare0 > > + $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls \ > > + -mstack-protector-guard-reg=tp \ > > + -mstack-protector-guard-offset=$(shell \ > > + awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \ > > + include/generated/asm-offsets.h)) > > +endif > > + > > # arch specific predefines for sparse > > CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS) > > > > diff --git a/arch/riscv/include/asm/stackprotector.h b/arch/riscv/include/asm/stackprotector.h > > index d95f7b2..a895e07 100644 > > --- a/arch/riscv/include/asm/stackprotector.h > > +++ b/arch/riscv/include/asm/stackprotector.h > > @@ -28,6 +28,7 @@ static __always_inline void boot_init_stack_canary(void) > > canary &= CANARY_MASK; > > > > current->stack_canary = canary; > > - __stack_chk_guard = current->stack_canary; > > + if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK)) > > + __stack_chk_guard = current->stack_canary; > > } > > #endif /* _ASM_RISCV_STACKPROTECTOR_H */ > > diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c > > index 07cb9c1..999b465 100644 > > --- a/arch/riscv/kernel/asm-offsets.c > > +++ b/arch/riscv/kernel/asm-offsets.c > > @@ -29,6 +29,9 @@ void asm_offsets(void) > > OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]); > > OFFSET(TASK_THREAD_SP, task_struct, thread.sp); > > OFFSET(TASK_STACK, task_struct, stack); > > +#ifdef CONFIG_STACKPROTECTOR > > Should this be CONFIG_STACKPROTECTOR_PER_TASK ? Yes, it's more accurate, Thx. I also send a patch [1] to arm64, and let's see how they reply? [1] https://lore.kernel.org/linux-csky/1594613013-13059-1-git-send-email-guoren@kernel.org/T/#u -- Best Regards Guo Ren ML: https://lore.kernel.org/linux-csky/ _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] riscv: Enable per-task stack canaries 2020-07-10 16:19 ` [PATCH v3 2/2] riscv: Enable per-task stack canaries guoren 2020-07-13 2:39 ` Kees Cook @ 2020-07-14 21:37 ` Palmer Dabbelt 2020-07-15 3:14 ` cooper 1 sibling, 1 reply; 6+ messages in thread From: Palmer Dabbelt @ 2020-07-14 21:37 UTC (permalink / raw) To: guoren Cc: guoren, keescook, anup, Paul Walmsley, linux-kernel, linux-csky, Atish Patra, guoren, zong.li, Bjorn Topel, cooper.qu, greentime.hu, linux-riscv On Fri, 10 Jul 2020 09:19:58 PDT (-0700), guoren@kernel.org wrote: > From: Guo Ren <guoren@linux.alibaba.com> > > This enables the use of per-task stack canary values if GCC has > support for emitting the stack canary reference relative to the > value of tp, which holds the task struct pointer in the riscv > kernel. > > After compare arm64 and x86 implementations, seems arm64's is more > flexible and readable. The key point is how gcc get the offset of > stack_canary from gs/el0_sp. > > x86: Use a fix offset from gs, not flexible. > > struct fixed_percpu_data { > /* > * GCC hardcodes the stack canary as %gs:40. Since the > * irq_stack is the object at %gs:0, we reserve the bottom > * 48 bytes of the irq stack for the canary. > */ > char gs_base[40]; // :( > unsigned long stack_canary; > }; > > arm64: Use -mstack-protector-guard-offset & guard-reg > gcc options: > -mstack-protector-guard=sysreg > -mstack-protector-guard-reg=sp_el0 > -mstack-protector-guard-offset=xxx > > riscv: Use -mstack-protector-guard-offset & guard-reg > gcc options: > -mstack-protector-guard=tls > -mstack-protector-guard-reg=tp > -mstack-protector-guard-offset=xxx > > Here is riscv gcc's work [1]. > > [1] https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549583.html > > In the end, these codes are inserted by gcc before return: > > * 0xffffffe00020b396 <+120>: ld a5,1008(tp) # 0x3f0 > * 0xffffffe00020b39a <+124>: xor a5,a5,a4 > * 0xffffffe00020b39c <+126>: mv a0,s5 > * 0xffffffe00020b39e <+128>: bnez a5,0xffffffe00020b61c <_do_fork+766> > 0xffffffe00020b3a2 <+132>: ld ra,136(sp) > 0xffffffe00020b3a4 <+134>: ld s0,128(sp) > 0xffffffe00020b3a6 <+136>: ld s1,120(sp) > 0xffffffe00020b3a8 <+138>: ld s2,112(sp) > 0xffffffe00020b3aa <+140>: ld s3,104(sp) > 0xffffffe00020b3ac <+142>: ld s4,96(sp) > 0xffffffe00020b3ae <+144>: ld s5,88(sp) > 0xffffffe00020b3b0 <+146>: ld s6,80(sp) > 0xffffffe00020b3b2 <+148>: ld s7,72(sp) > 0xffffffe00020b3b4 <+150>: addi sp,sp,144 > 0xffffffe00020b3b6 <+152>: ret > ... > * 0xffffffe00020b61c <+766>: auipc ra,0x7f8 > * 0xffffffe00020b620 <+770>: jalr -1764(ra) # 0xffffffe000a02f38 <__stack_chk_fail> > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > Signed-off-by: cooper <cooper.qu@linux.alibaba.com> IIRC we're required to use full names here. I'm assuming that's meant to be "Signed-off-by: Cooper Qu ...", and I know it's a bit procedural but I can't make that change. Otherwise these two look good, the first one is on for-next. I can boot with a defconfig ammended with CONFIG_STACKPROTECTOR=y, Thanks! > Cc: cooper <cooper.qu@linux.alibaba.com> > Cc: Kees Cook <keescook@chromium.org> > --- > Change v2: > - Change to -mstack-protector-guard=tls for gcc final define > - Solve compile error by changing position of KBUILD_CFLAGS in > Makefile > > Signed-off-by: Guo Ren <guoren@linux.alibaba.com> > --- > arch/riscv/Kconfig | 7 +++++++ > arch/riscv/Makefile | 10 ++++++++++ > arch/riscv/include/asm/stackprotector.h | 3 ++- > arch/riscv/kernel/asm-offsets.c | 3 +++ > arch/riscv/kernel/process.c | 2 +- > 5 files changed, 23 insertions(+), 2 deletions(-) > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > index 4b0e308..d98ce29 100644 > --- a/arch/riscv/Kconfig > +++ b/arch/riscv/Kconfig > @@ -394,6 +394,13 @@ config CMDLINE_FORCE > > endchoice > > +config CC_HAVE_STACKPROTECTOR_TLS > + def_bool $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=tp -mstack-protector-guard-offset=0) > + > +config STACKPROTECTOR_PER_TASK > + def_bool y > + depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_TLS > + > endmenu > > config BUILTIN_DTB > diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile > index fb6e37d..f5f8ee9 100644 > --- a/arch/riscv/Makefile > +++ b/arch/riscv/Makefile > @@ -68,6 +68,16 @@ KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) > # architectures. It's faster to have GCC emit only aligned accesses. > KBUILD_CFLAGS += $(call cc-option,-mstrict-align) > > +ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) > +prepare: stack_protector_prepare > +stack_protector_prepare: prepare0 > + $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls \ > + -mstack-protector-guard-reg=tp \ > + -mstack-protector-guard-offset=$(shell \ > + awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \ > + include/generated/asm-offsets.h)) > +endif > + > # arch specific predefines for sparse > CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS) > > diff --git a/arch/riscv/include/asm/stackprotector.h b/arch/riscv/include/asm/stackprotector.h > index d95f7b2..a895e07 100644 > --- a/arch/riscv/include/asm/stackprotector.h > +++ b/arch/riscv/include/asm/stackprotector.h > @@ -28,6 +28,7 @@ static __always_inline void boot_init_stack_canary(void) > canary &= CANARY_MASK; > > current->stack_canary = canary; > - __stack_chk_guard = current->stack_canary; > + if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK)) > + __stack_chk_guard = current->stack_canary; > } > #endif /* _ASM_RISCV_STACKPROTECTOR_H */ > diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c > index 07cb9c1..999b465 100644 > --- a/arch/riscv/kernel/asm-offsets.c > +++ b/arch/riscv/kernel/asm-offsets.c > @@ -29,6 +29,9 @@ void asm_offsets(void) > OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]); > OFFSET(TASK_THREAD_SP, task_struct, thread.sp); > OFFSET(TASK_STACK, task_struct, stack); > +#ifdef CONFIG_STACKPROTECTOR > + OFFSET(TSK_STACK_CANARY, task_struct, stack_canary); > +#endif > OFFSET(TASK_TI, task_struct, thread_info); > OFFSET(TASK_TI_FLAGS, task_struct, thread_info.flags); > OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count); > diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c > index 6548929..cb4ac65 100644 > --- a/arch/riscv/kernel/process.c > +++ b/arch/riscv/kernel/process.c > @@ -24,7 +24,7 @@ > > register unsigned long gp_in_global __asm__("gp"); > > -#ifdef CONFIG_STACKPROTECTOR > +#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) > #include <linux/stackprotector.h> > unsigned long __stack_chk_guard __read_mostly; > EXPORT_SYMBOL(__stack_chk_guard); _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] riscv: Enable per-task stack canaries 2020-07-14 21:37 ` Palmer Dabbelt @ 2020-07-15 3:14 ` cooper 0 siblings, 0 replies; 6+ messages in thread From: cooper @ 2020-07-15 3:14 UTC (permalink / raw) To: Palmer Dabbelt, guoren Cc: guoren, keescook, anup, Paul Walmsley, linux-kernel, linux-csky, Atish Patra, zong.li, Bjorn Topel, greentime.hu, linux-riscv On 2020/7/15 上午5:37, Palmer Dabbelt wrote: > On Fri, 10 Jul 2020 09:19:58 PDT (-0700), guoren@kernel.org wrote: >> From: Guo Ren <guoren@linux.alibaba.com> >> >> This enables the use of per-task stack canary values if GCC has >> support for emitting the stack canary reference relative to the >> value of tp, which holds the task struct pointer in the riscv >> kernel. >> >> After compare arm64 and x86 implementations, seems arm64's is more >> flexible and readable. The key point is how gcc get the offset of >> stack_canary from gs/el0_sp. >> >> x86: Use a fix offset from gs, not flexible. >> >> struct fixed_percpu_data { >> /* >> * GCC hardcodes the stack canary as %gs:40. Since the >> * irq_stack is the object at %gs:0, we reserve the bottom >> * 48 bytes of the irq stack for the canary. >> */ >> char gs_base[40]; // :( >> unsigned long stack_canary; >> }; >> >> arm64: Use -mstack-protector-guard-offset & guard-reg >> gcc options: >> -mstack-protector-guard=sysreg >> -mstack-protector-guard-reg=sp_el0 >> -mstack-protector-guard-offset=xxx >> >> riscv: Use -mstack-protector-guard-offset & guard-reg >> gcc options: >> -mstack-protector-guard=tls >> -mstack-protector-guard-reg=tp >> -mstack-protector-guard-offset=xxx >> >> Here is riscv gcc's work [1]. >> >> [1] https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549583.html >> >> In the end, these codes are inserted by gcc before return: >> >> * 0xffffffe00020b396 <+120>: ld a5,1008(tp) # 0x3f0 >> * 0xffffffe00020b39a <+124>: xor a5,a5,a4 >> * 0xffffffe00020b39c <+126>: mv a0,s5 >> * 0xffffffe00020b39e <+128>: bnez a5,0xffffffe00020b61c >> <_do_fork+766> >> 0xffffffe00020b3a2 <+132>: ld ra,136(sp) >> 0xffffffe00020b3a4 <+134>: ld s0,128(sp) >> 0xffffffe00020b3a6 <+136>: ld s1,120(sp) >> 0xffffffe00020b3a8 <+138>: ld s2,112(sp) >> 0xffffffe00020b3aa <+140>: ld s3,104(sp) >> 0xffffffe00020b3ac <+142>: ld s4,96(sp) >> 0xffffffe00020b3ae <+144>: ld s5,88(sp) >> 0xffffffe00020b3b0 <+146>: ld s6,80(sp) >> 0xffffffe00020b3b2 <+148>: ld s7,72(sp) >> 0xffffffe00020b3b4 <+150>: addi sp,sp,144 >> 0xffffffe00020b3b6 <+152>: ret >> ... >> * 0xffffffe00020b61c <+766>: auipc ra,0x7f8 >> * 0xffffffe00020b620 <+770>: jalr -1764(ra) # >> 0xffffffe000a02f38 <__stack_chk_fail> >> >> Signed-off-by: Guo Ren <guoren@linux.alibaba.com> >> Signed-off-by: cooper <cooper.qu@linux.alibaba.com> > > IIRC we're required to use full names here. I'm assuming that's meant > to be > "Signed-off-by: Cooper Qu ...", and I know it's a bit procedural but I > can't > make that change. > > Otherwise these two look good, the first one is on for-next. I can > boot with a > defconfig ammended with CONFIG_STACKPROTECTOR=y, > Thanks! > Hi Palmer, That's ok to change it to full names as follows. Signed-off-by: Cooper Qu <cooper.qu@linux.alibaba.com> Best Regards, Cooper _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-07-15 3:15 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-07-10 16:19 [PATCH v3 1/2] riscv: Add STACKPROTECTOR supported guoren 2020-07-10 16:19 ` [PATCH v3 2/2] riscv: Enable per-task stack canaries guoren 2020-07-13 2:39 ` Kees Cook 2020-07-13 4:05 ` Guo Ren 2020-07-14 21:37 ` Palmer Dabbelt 2020-07-15 3:14 ` cooper
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).