[Skiboot] [PATCH v2 1/3] Add support for new gcc 7 parametrized stack protector

Benjamin Herrenschmidt benh at kernel.crashing.org
Wed Dec 20 13:16:21 AEDT 2017


This gives us per-cpu guard values as well. For now I just
xor a magic constant with the CPU PIR value.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---

v2. Remove obsolete comment in Makefile.main
---
 Makefile.main   | 26 ++++++++++++++++++--------
 asm/head.S      |  5 +++++
 core/cpu.c      | 12 ++++++++++--
 core/utils.c    |  3 ---
 include/cpu.h   |  5 +++++
 include/stack.h |  2 ++
 6 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/Makefile.main b/Makefile.main
index 31cbab7e..516afdd6 100644
--- a/Makefile.main
+++ b/Makefile.main
@@ -19,6 +19,7 @@ try = $(shell set -e; if ($(1)) >/dev/null 2>&1; \
 	else echo "$(3)"; fi )
 
 try-cflag = $(call try,$(1) $(2) -x c -c /dev/null -o /dev/null,$(2))
+test_cflag = $(call try,$(1) $(2) -x c -c /dev/null -o /dev/null,1,0)
 
 # Base warnings
 CWARNS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
@@ -90,20 +91,29 @@ else
 VALGRIND :=
 endif
 
-# Stack protector disabled for now. gcc tends to use the TLS to
-# access the canary (depending on how gcc was built), and this won't
-# work for us.
-#
+# Check if the new parametrized stack protector option is supported
+# by gcc, otherwise disable stack protector
+STACK_PROT_CFLAGS := -mstack-protector-guard=tls -mstack-protector-guard-reg=r13
+STACK_PROT_CFLAGS += -mstack-protector-guard-offset=0
+HAS_STACK_PROT := $(call test_cflag,$(CC),$(STACK_PROT_CFLAGS))
+
 ifeq ($(STACK_CHECK),1)
-#CFLAGS += -fstack-protector-all -pg
-CFLAGS += -fno-stack-protector -pg
+STACK_PROT_CFLAGS += -fstack-protector-all
 CPPFLAGS += -DSTACK_CHECK_ENABLED
+CFLAGS += -pg
+else
+STACK_PROT_CFLAGS += -fstack-protector
+STACK_PROT_CFLAGS += $(call try-cflag,$(CC),-fstack-protector-strong)
+endif
+
+ifeq ($(HAS_STACK_PROT),1)
+CPPFLAGS += -DHAS_STACK_PROT
+CFLAGS += $(STACK_PROT_CFLAGS)
 else
 CFLAGS += -fno-stack-protector
-#CFLAGS += -fstack-protector
-#CFLAGS += $(call try-cflag,$(CC),-fstack-protector-strong)
 endif
 
+
 CFLAGS += $(call try-cflag,$(CC),-Wjump-misses-init) \
 	  $(call try-cflag,$(CC),-Wsuggest-attribute=const) \
 	  $(call try-cflag,$(CC),-Wsuggest-attribute=noreturn) \
diff --git a/asm/head.S b/asm/head.S
index eccf0702..264899b1 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -389,6 +389,11 @@ boot_entry:
 	li	%r0,0
 	std	%r0,CPUTHREAD_STACK_BOT_MARK(%r13)
 #endif
+	/* Initialize the stack guard */
+	LOAD_IMM64(%r3,STACK_CHECK_GUARD_BASE);
+	xor	%r3,%r3,%r31
+	std	%r3,0(%r13)
+
 	/* Jump to C */
 	mr	%r3,%r27
 	bl	main_cpu_entry
diff --git a/core/cpu.c b/core/cpu.c
index b94e04ef..7dd7c863 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -822,6 +822,7 @@ static void init_cpu_thread(struct cpu_thread *t,
 	init_lock(&t->dctl_lock);
 	init_lock(&t->job_lock);
 	list_head_init(&t->job_queue);
+	t->stack_guard = STACK_CHECK_GUARD_BASE ^ pir;
 	t->state = state;
 	t->pir = pir;
 #ifdef STACK_CHECK_ENABLED
@@ -865,7 +866,8 @@ void __nomcount pre_init_boot_cpu(void)
 {
 	struct cpu_thread *cpu = this_cpu();
 
-	memset(cpu, 0, sizeof(struct cpu_thread));
+	/* We skip the stack guard ! */
+	memset(((void *)cpu) + 8, 0, sizeof(struct cpu_thread) - 8);
 }
 
 void init_boot_cpu(void)
@@ -943,8 +945,14 @@ void init_boot_cpu(void)
 	top_of_ram += (cpu_max_pir + 1) * STACK_SIZE;
 
 	/* Clear the CPU structs */
-	for (i = 0; i <= cpu_max_pir; i++)
+	for (i = 0; i <= cpu_max_pir; i++) {
+		/* boot CPU already cleared and we don't want to clobber
+		 * its stack guard value.
+		 */
+		if (i == pir)
+			continue;
 		memset(&cpu_stacks[i].cpu, 0, sizeof(struct cpu_thread));
+	}
 
 	/* Setup boot CPU state */
 	boot_cpu = &cpu_stacks[pir].cpu;
diff --git a/core/utils.c b/core/utils.c
index d21881ef..9e2cb37c 100644
--- a/core/utils.c
+++ b/core/utils.c
@@ -22,9 +22,6 @@
 #include <cpu.h>
 #include <stack.h>
 
-extern unsigned long __stack_chk_guard;
-unsigned long __stack_chk_guard = 0xdeadf00dbaad300dULL;
-
 void __noreturn assert_fail(const char *msg)
 {
 	/**
diff --git a/include/cpu.h b/include/cpu.h
index 28041057..e3bc75f4 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -45,6 +45,11 @@ struct cpu_job;
 struct xive_cpu_state;
 
 struct cpu_thread {
+	/*
+	 * "stack_guard" must be at offset 0 to match the
+	 * -mstack-protector-guard-offset=0 statement in the Makefile
+	 */
+	uint64_t			stack_guard;
 	uint32_t			pir;
 	uint32_t			server_no;
 	uint32_t			chip_id;
diff --git a/include/stack.h b/include/stack.h
index 3c9799b1..e50b34f0 100644
--- a/include/stack.h
+++ b/include/stack.h
@@ -44,6 +44,8 @@
  */
 #define STACK_WARNING_GAP	2048
 
+#define STACK_CHECK_GUARD_BASE	0xdeadf00dbaad300
+
 #ifndef __ASSEMBLY__
 
 #include <stdint.h>
-- 
2.14.3



More information about the Skiboot mailing list