From patchwork Wed Jul 12 22:33:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 107539 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp1412135qge; Wed, 12 Jul 2017 15:34:50 -0700 (PDT) X-Received: by 10.98.13.219 with SMTP id 88mr58860006pfn.191.1499898889892; Wed, 12 Jul 2017 15:34:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499898889; cv=none; d=google.com; s=arc-20160816; b=dIiH9ZJvHyoh2VN59EFlPZOXAvkm1VQNw/eBRT92qcnrVxEeWSTtrTR4wF7FDZfeDI hAiMkwGEk9PZX2DhB+rugM+b/c0++kxZdH61kNsHiST3a5Ehgeh18yxYy35az0xJHpsv T7dvZo6haK5KBzO5NB6zGunBI2lYh9xoSfGZvReUyvLekkXxoPYKiIeCokMo6HrN9HbO mHElFPcGpnkvaWHU1z715q58s8b61AeaZ64rM5rsImB7sX+GIYvTsYZDN0q+9tiNwH0P TJQGtIlVjI7tvkHzNYg1yPYaynyaT0+bCAtdaHsQmfY+iISoDjetdS6d1iGAR+6OAiwi W/Hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=lu70MI5Id7Kqvpq0jS1OI00LkZk+Tter51ms4Hfk8+c=; b=TJdLnjGenuR8ApT+Yj2Lds6y+9DcUI1wANEjICK7kA3gTjg9WXWemjz0clYOVgsdLD +r2+mU1aU76PoU+XssZ0AGWfDngoDCZY7Uu2aa2IvY7bdZtEgtOyGoYEdb6LwMOTOCAG oWgjdVBPj8c+a5fY6R9mwSa+P8njCbj68Le23NcDpP6ImW+YN+EAzp7EI9ns5To2YmcE w34zGoey9WhOskRLs6oBhAcQmUT+HqGCfq5Jx+uo6VoqblgU0mOaQR0LQMZEd0nZXOoo pRtirwyhKUZWjCy3qWjMeWf6z2z5z29Odvw+2fJ+4HAx1mVpqhhHBAV5YOMp00x58ZS5 NSIA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 31si2955233plk.116.2017.07.12.15.34.49; Wed, 12 Jul 2017 15:34:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752833AbdGLWeb (ORCPT + 25 others); Wed, 12 Jul 2017 18:34:31 -0400 Received: from foss.arm.com ([217.140.101.70]:59132 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751883AbdGLWe2 (ORCPT ); Wed, 12 Jul 2017 18:34:28 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6F8041650; Wed, 12 Jul 2017 15:34:18 -0700 (PDT) Received: from leverpostej.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8EF303F3E1; Wed, 12 Jul 2017 15:34:16 -0700 (PDT) From: Mark Rutland To: ard.biesheuvel@linaro.org, kernel-hardening@lists.openwall.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: akashi.takahiro@linaro.org, catalin.marinas@arm.com, dave.martin@arm.com, james.morse@arm.com, labbott@fedoraproject.org, will.deacon@arm.com, keescook@chromium.org, Mark Rutland Subject: [RFC PATCH 6/6] arm64: add VMAP_STACK and detect out-of-bounds SP Date: Wed, 12 Jul 2017 23:33:03 +0100 Message-Id: <1499898783-25732-7-git-send-email-mark.rutland@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1499898783-25732-1-git-send-email-mark.rutland@arm.com> References: <1499898783-25732-1-git-send-email-mark.rutland@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Signed-off-by: Mark Rutland --- arch/arm64/Kconfig | 1 + arch/arm64/kernel/entry.S | 43 +++++++++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/traps.c | 21 +++++++++++++++++++++ 3 files changed, 65 insertions(+) -- 1.9.1 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index b2024db..5cbd961 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1,5 +1,6 @@ config ARM64 def_bool y + select HAVE_ARCH_VMAP_STACK select ACPI_CCA_REQUIRED if ACPI select ACPI_GENERIC_GSI if ACPI select ACPI_GTDT if ACPI diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 7c8b164..e0fdb65 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -396,11 +396,54 @@ el1_error_invalid: inv_entry 1, BAD_ERROR ENDPROC(el1_error_invalid) +#ifdef CONFIG_VMAP_STACK +.macro detect_bad_stack + msr sp_el0, x0 + get_thread_info x0 + ldr x0, [x0, #TSK_TI_CUR_STK] + sub x0, sp, x0 + and x0, x0, #~(THREAD_SIZE - 1) + cbnz x0, __bad_stack + mrs x0, sp_el0 +.endm + +__bad_stack: + /* + * Stash the bad SP, and free up another GPR. We no longer care about + * EL0 state, since this thread cannot recover. + */ + mov x0, sp + msr tpidrro_el0, x0 + msr tpidr_el0, x1 + + /* Move to the emergency stack */ + adr_this_cpu x0, bad_stack, x1 + mov x1, #THREAD_START_SP + add sp, x0, x1 + + /* Restore GPRs and log them to pt_regs */ + mrs x0, sp_el0 + mrs x1, tpidr_el0 + kernel_entry 1 + + /* restore the bad SP to pt_regs */ + mrs x1, tpidrro_el0 + str x1, [sp, #S_SP] + + /* Time to die */ + mov x0, sp + b handle_bad_stack +#else +.macro detect_bad_stack +.endm +#endif + /* * EL1 mode handlers. */ .align 6 el1_sync: + detect_bad_stack kernel_entry 1 mrs x1, esr_el1 // read the syndrome register lsr x24, x1, #ESR_ELx_EC_SHIFT // exception class diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 0805b44..84b00e3 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -683,6 +683,27 @@ asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr) force_sig_info(info.si_signo, &info, current); } +#ifdef CONFIG_VMAP_STACK +DEFINE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], bad_stack) __aligned(16); + +asmlinkage void handle_bad_stack(struct pt_regs *regs) +{ + unsigned long tsk_stk = (unsigned long)current->stack; + unsigned long irq_stk = (unsigned long)per_cpu(irq_stack, smp_processor_id()); + + console_verbose(); + pr_emerg("Stack out-of-bounds!\n" + "\tsp: 0x%016lx\n" + "\ttsk stack: [0x%016lx..0x%016lx]\n" + "\tirq stack: [0x%016lx..0x%016lx]\n", + kernel_stack_pointer(regs), + tsk_stk, tsk_stk + THREAD_SIZE, + irq_stk, irq_stk + THREAD_SIZE); + show_regs(regs); + panic("stack out-of-bounds"); +} +#endif + void __pte_error(const char *file, int line, unsigned long val) { pr_err("%s:%d: bad pte %016lx.\n", file, line, val);