From patchwork Wed Dec 6 17:38:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 845298 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ysT155hfKz9s4q for ; Thu, 7 Dec 2017 06:18:33 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3ysT153GcMzDsM9 for ; Thu, 7 Dec 2017 06:18:33 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3ysT0X1J3LzDsFq for ; Thu, 7 Dec 2017 06:18:03 +1100 (AEDT) Received: from localhost (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id vB6Hcoul020737 for ; Wed, 6 Dec 2017 11:38:56 -0600 Message-ID: <1512581930.2224.130.camel@kernel.crashing.org> From: Benjamin Herrenschmidt To: skiboot@lists.ozlabs.org Date: Wed, 06 Dec 2017 11:38:50 -0600 X-Mailer: Evolution 3.26.2 (3.26.2-1.fc27) Mime-Version: 1.0 Subject: [Skiboot] [PATCH] Add support for new gcc 7 parametrized stack protector X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" 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 --- Makefile.main | 22 ++++++++++++++++++---- 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(+), 9 deletions(-) diff --git a/Makefile.main b/Makefile.main index 73c91962..035b72d1 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 \ @@ -84,20 +85,33 @@ ifeq ($(SKIBOOT_GCOV),1) CFLAGS += -fprofile-arcs -ftest-coverage -DSKIBOOT_GCOV=1 endif +# 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)) + # 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. # 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 #include -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