From patchwork Fri May 24 10:25:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 165101 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp3384486ili; Fri, 24 May 2019 03:26:42 -0700 (PDT) X-Google-Smtp-Source: APXvYqxFqSaU1sNuxEOc4K7BVpXd1W6+xO7Dmo8x65Tsej+0W0Kc+5BiEzt+jv80TDrz8Yn7w4gR X-Received: by 2002:a62:4281:: with SMTP id h1mr112597341pfd.162.1558693602695; Fri, 24 May 2019 03:26:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558693602; cv=none; d=google.com; s=arc-20160816; b=SwReuOw2BhN8jes63SeGQF/Fl5ZER7Tk4YIY2hhXUei5vGCpK9HmB2Au0B+EbtAhNk EVkZdPFTEGWQkF4+cdjvqTnGapX4UdKuF/ceMUStj9RvfSRMbjiXRPfrOWxD9s5y9DjO wlapJki6sfbccC8m4GEWc2KA1Clr3qwenL9PFYcez7KFcQTpqHlriC/kFMZiCCtSxjJW SFDvytcSyFzyO+P3i/uaEAI4BO6fdqBl1EXdFX/cqXsJL+slLgT1VL37OAJWVZ01nmbZ OTL4kDOHZMwK8ltys+CFVebNrCB++ecrtqO8V93omb9+FVGyMM3WXW4hYiOsgW7ljFRH 5olQ== 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; bh=SZrVVEHo9rNgYciBBTnlUT+PvibdBNOipKlcD0vrPkQ=; b=sfS3DF19gKZgDtmVRZcKw2aBsYS6+SMqFllskT9vh29li59Wninz/t9Nf+G3wribyC 9RBgcC0lxmTZ666/DTBZk7AeqKW40MTLgJTh6icafLXe7TuNhZDnhHFLEbwUgQ8ms1vf uNHNjm41k3C/ym/LC5d4Ccj08rPtK2lv8i0VpeziOTTRyg8KpeMS/Z2b9mjH11CzIQti h7zUXufwbGU0h+5g9SUCK3Ui3Fg0/NJWIm/jmg9sRKGkd2ckL26TJPxcZLUpdQ+25xA+ M05+zWO1aTRYwSEahp1VsTHqRRWXMLAWnE1V5ztW7p9VJ7ss+vHBFykmX3mcs8YH6BiY /q7Q== 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 x65si3726705pfd.44.2019.05.24.03.26.42; Fri, 24 May 2019 03:26:42 -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 S2390695AbfEXK0l (ORCPT + 30 others); Fri, 24 May 2019 06:26:41 -0400 Received: from foss.arm.com ([217.140.101.70]:39296 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390672AbfEXK0j (ORCPT ); Fri, 24 May 2019 06:26:39 -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 0D5C015A2; Fri, 24 May 2019 03:26:39 -0700 (PDT) Received: from e103592.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 C967A3F703; Fri, 24 May 2019 03:26:36 -0700 (PDT) From: Dave Martin To: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, Yu-cheng Yu , "H.J. Lu" , Arnd Bergmann , Richard Henderson , Andrew Jones , Will Deacon , Catalin Marinas , =?utf-8?q?Kristina_Mart=C5=A1enko?= , Szabolcs Nagy , Sudakshina Das , Paul Elliott Subject: [PATCH 7/8] arm64: elf: Enable BTI at exec based on ELF program properties Date: Fri, 24 May 2019 11:25:32 +0100 Message-Id: <1558693533-13465-8-git-send-email-Dave.Martin@arm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1558693533-13465-1-git-send-email-Dave.Martin@arm.com> References: <1558693533-13465-1-git-send-email-Dave.Martin@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org For BTI protection to be as comprehensive as possible, it is desirable to have BTI enabled from process startup. If this is not done, the process must use mprotect() to enable BTI for each of its executable mappings, but this is painful to do in the libc startup code. It's simpler and more sound to have the kernel do it instead. To this end, detect BTI support in the executable (or ELF interpreter, as appropriate), via the NT_GNU_PROGRAM_PROPERTY_TYPE_0 note, and tweak the initial prot flags for the process' executable pages to include PROT_BTI_GUARDED as appropriate. Signed-off-by: Dave Martin --- arch/arm64/Kconfig | 3 +++ arch/arm64/include/asm/elf.h | 28 ++++++++++++++++++++++ arch/arm64/kernel/process.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/elf.h | 8 ++++++- 4 files changed, 93 insertions(+), 1 deletion(-) -- 2.1.4 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 0f6765e..f8af7f2 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -8,6 +8,7 @@ config ARM64 select ACPI_MCFG if (ACPI && PCI) select ACPI_SPCR_TABLE if ACPI select ACPI_PPTT if ACPI + select ARCH_BINFMT_ELF_STATE select ARCH_CLOCKSOURCE_DATA select ARCH_HAS_DEBUG_VIRTUAL select ARCH_HAS_DEVMEM_IS_ALLOWED @@ -33,6 +34,7 @@ config ARM64 select ARCH_HAS_SYSCALL_WRAPPER select ARCH_HAS_TEARDOWN_DMA_OPS if IOMMU_SUPPORT select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST + select ARCH_HAVE_ELF_PROT select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_INLINE_READ_LOCK if !PREEMPT select ARCH_INLINE_READ_LOCK_BH if !PREEMPT @@ -62,6 +64,7 @@ config ARM64 select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE if !PREEMPT select ARCH_KEEP_MEMBLOCK select ARCH_USE_CMPXCHG_LOCKREF + select ARCH_USE_GNU_PROPERTY if BINFMT_ELF select ARCH_USE_QUEUED_RWLOCKS select ARCH_USE_QUEUED_SPINLOCKS select ARCH_SUPPORTS_MEMORY_FAILURE diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 355d120..bba45fa 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -126,6 +126,7 @@ #ifndef __ASSEMBLY__ #include +#include #include /* for signal_minsigstksz, used by ARCH_DLINFO */ typedef unsigned long elf_greg_t; @@ -221,6 +222,33 @@ extern int aarch32_setup_additional_pages(struct linux_binprm *bprm, #endif /* CONFIG_COMPAT */ +struct arch_elf_state { + int flags; +}; + +#define ARM64_ELF_BTI (1 << 0) + +#define INIT_ARCH_ELF_STATE { \ + .flags = 0, \ +} + +int arch_parse_property(void *ehdr, void *phdr, struct file *f, bool interp, + struct arch_elf_state *state); + +static inline int arch_elf_pt_proc(void *ehdr, void *phdr, + struct file *f, bool is_interp, + struct arch_elf_state *state) +{ + return 0; +} + +static inline int arch_check_elf(void *ehdr, bool has_interp, + void *interp_ehdr, + struct arch_elf_state *state) +{ + return 0; +} + #endif /* !__ASSEMBLY__ */ #endif diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 3767fb2..104b0d8 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -22,12 +22,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -552,3 +554,56 @@ void arch_setup_new_exec(void) ptrauth_thread_init_user(current); } + +#ifdef CONFIG_BINFMT_ELF +int arch_parse_property(void *ehdr, void *phdr, struct file *f, bool interp, + struct arch_elf_state *state) +{ + union any_elf_hdr { + struct elf32_hdr hdr32; + struct elf64_hdr hdr64; + }; + const union any_elf_hdr *e = ehdr; + + int ret; + u32 val; + + /* Currently we have GNU program properties only for native: */ + if (e->hdr64.e_machine != EM_AARCH64) { + WARN_ON(!IS_ENABLED(CONFIG_COMPAT) || + e->hdr64.e_machine != EM_ARM); + + return 0; + } + + ret = get_gnu_property(ehdr, phdr, f, + GNU_PROPERTY_AARCH64_FEATURE_1_AND, + &val); + if (ret) + return ret; + + if (val & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) { + if (!system_supports_bti()) + return -EINVAL; + + state->flags |= ARM64_ELF_BTI; + } + + return 0; +} + +int arch_elf_adjust_prot(int prot, const struct arch_elf_state *state, + bool has_interp, bool is_interp) +{ + if (is_interp != has_interp) + return prot; + + if (!(state->flags & ARM64_ELF_BTI)) + return prot; + + if (prot & PROT_EXEC) + prot |= PROT_BTI_GUARDED; + + return prot; +} +#endif diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index 7b7603a..1c8e455 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -444,11 +444,17 @@ typedef struct elf64_note { Elf64_Word n_type; /* Content type */ } Elf64_Nhdr; -/* .note.gnu.property types */ +/* .note.gnu.property types for x86: */ #define GNU_PROPERTY_X86_FEATURE_1_AND (0xc0000002) /* Bits of GNU_PROPERTY_X86_FEATURE_1_AND */ #define GNU_PROPERTY_X86_FEATURE_1_IBT (0x00000001) #define GNU_PROPERTY_X86_FEATURE_1_SHSTK (0x00000002) +/* .note.gnu.property types for EM_AARCH64: */ +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 + +/* Bits for GNU_PROPERTY_AARCH64_FEATURE_1_BTI */ +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) + #endif /* _UAPI_LINUX_ELF_H */