From patchwork Fri May 24 10:25:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 165095 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp3384250ili; Fri, 24 May 2019 03:26:26 -0700 (PDT) X-Google-Smtp-Source: APXvYqzyRGsAfm7d3zg8v8J1ottfo4qtmGCIlSvfF/b+nUXwvFWl6cbWvJPY7yERPg4Y+Ha3cYSA X-Received: by 2002:a17:90a:aa88:: with SMTP id l8mr8062581pjq.65.1558693586419; Fri, 24 May 2019 03:26:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558693586; cv=none; d=google.com; s=arc-20160816; b=qQ9x5/Olaz2XfdbuSlCUNL1/rViDi80Ck0Cezw9kS0OHBosw1aj9+UWlHmOPs6FE+X RdTFmU0v/xlfr9GYLu6d7YRXyt/RRLvI0en75qJdVtSD5Qnv3Mw9tNp88LMnuDJlX567 8KbJTIjRpWKE7ww8CjFRHpaSuH1V2CbcaH1i2uKQtKVupGZIRKhFoVjWabE5TLPPtT43 75TN28QT+0APBY2QLS3P0zJh9pGSmZGRhpwOJLWVI8mvvMtso1S7QnR4atUSGFFJcYSp mqfstuyD6bbIj+zVuCajyglAROp8j4pejbwyl+Siw3AKPBEHt1JthEpQXT+754BiSfLe Tj7g== 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=DWT2+68l6+Q+VUmvhnfygMTt7FssCnDr2HQ8qcfA4fs=; b=mG9XFCNNtPcPjcDnWYirxgH7ebZzfZ3d1XqbbtSL/gIO0w49oMXK2vijLxZhlz/nEG z/RU1GVC7sCIK6ruzfi2xilZr8jDLuwv1ubsyb4G2LLE2P1smBFTAC+jhrzIlul1/FVM 6enM9h7vF6l4bq1TxxWtooZSkWO/bcd9dnz3annwr9g2BJjL0ZI1ag9cflvPteUME2nb mGjLLC0dEDKz17vgMBjIhSxQFdQT+HKGx2M78RtriPBYoE3hDPBGGNH0BJDQsAaOohGR mdLttUUuFiYwUuiG/5w/+popNaLEWNXEaiU8F/5vD1dC+gHFw+PTJ28Sd0lj2fk9BBZg cvFA== 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 n189si3225267pgn.581.2019.05.24.03.26.26; Fri, 24 May 2019 03:26:26 -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 S2390552AbfEXK0Z (ORCPT + 30 others); Fri, 24 May 2019 06:26:25 -0400 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:39176 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389942AbfEXK0Z (ORCPT ); Fri, 24 May 2019 06:26:25 -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 D8072A78; Fri, 24 May 2019 03:26:23 -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 7C5523F703; Fri, 24 May 2019 03:26:21 -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 1/8] binfmt_elf: Extract .note.gnu.property from an ELF file Date: Fri, 24 May 2019 11:25:26 +0100 Message-Id: <1558693533-13465-2-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 From: Yu-cheng Yu An ELF file's .note.gnu.property indicates features the executable file can support. For example, the property GNU_PROPERTY_X86_FEATURE_1_AND indicates the file supports GNU_PROPERTY_X86_FEATURE_1_IBT and/or GNU_PROPERTY_X86_FEATURE_1_SHSTK. This patch was part of the Control-flow Enforcement series; the original patch is here: https://lkml.org/lkml/2018/11/20/205. Dave Martin responded that ARM recently introduced new features to NT_GNU_PROPERTY_TYPE_0 with properties closely modelled on GNU_PROPERTY_X86_FEATURE_1_AND, and it is logical to split out the generic part. Here it is. With this patch, if an arch needs to setup features from ELF properties, it needs CONFIG_ARCH_USE_GNU_PROPERTY to be set, and a specific arch_setup_property(). For example, for X86_64: int arch_setup_property(void *ehdr, void *phdr, struct file *f, bool inter) { int r; uint32_t property; r = get_gnu_property(ehdr, phdr, f, GNU_PROPERTY_X86_FEATURE_1_AND, &property); ... } Signed-off-by: H.J. Lu Signed-off-by: Yu-cheng Yu Signed-off-by: Dave Martin [rebase to v5.2-rc1] --- Notes from Dave: * For arm64 at least, I'm hoping we can rely on the PT_GNU_PROPERTY program header to find the program properties. If this works for x86 too, I think the code could be simplified considerably. Ideally we would always use that: having to exhaustively search all the notes in the image instead doesn't feel like the right design IMHO. This needs further discussion, and I make no attempt to address it for now. --- fs/Kconfig.binfmt | 4 + fs/Makefile | 1 + fs/binfmt_elf.c | 13 ++ fs/gnu_property.c | 363 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/elf.h | 12 ++ include/uapi/linux/elf.h | 8 ++ 6 files changed, 401 insertions(+) create mode 100644 fs/gnu_property.c -- 2.1.4 diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index b795f8d..175a1f5 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt @@ -35,6 +35,10 @@ config COMPAT_BINFMT_ELF config ARCH_BINFMT_ELF_STATE bool +config ARCH_USE_GNU_PROPERTY + bool + depends on 64BIT + config BINFMT_ELF_FDPIC bool "Kernel support for FDPIC ELF binaries" default y if !BINFMT_ELF diff --git a/fs/Makefile b/fs/Makefile index c9aea23..b69f18c 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o +obj-$(CONFIG_ARCH_USE_GNU_PROPERTY) += gnu_property.o obj-$(CONFIG_FS_MBCACHE) += mbcache.o obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index fa9e99a..18015fc 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1080,6 +1080,19 @@ static int load_elf_binary(struct linux_binprm *bprm) } if (interpreter) { + retval = arch_setup_property(&loc->interp_elf_ex, + interp_elf_phdata, + interpreter, true); + } else { + retval = arch_setup_property(&loc->elf_ex, + elf_phdata, + bprm->file, false); + } + + if (retval < 0) + goto out_free_dentry; + + if (interpreter) { unsigned long interp_map_addr = 0; elf_entry = load_elf_interp(&loc->interp_elf_ex, diff --git a/fs/gnu_property.c b/fs/gnu_property.c new file mode 100644 index 0000000..656ea39 --- /dev/null +++ b/fs/gnu_property.c @@ -0,0 +1,363 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Extract an ELF file's .note.gnu.property. + * + * The path from the ELF header to the note section is the following: + * elfhdr->elf_phdr->elf_note->property[]. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The .note.gnu.property layout: + * + * struct elf_note { + * u32 n_namesz; --> sizeof(n_name[]); always (4) + * u32 n_ndescsz;--> sizeof(property[]) + * u32 n_type; --> always NT_GNU_PROPERTY_TYPE_0 + * }; + * char n_name[4]; --> always 'GNU\0' + * + * struct { + * struct gnu_property { + * u32 pr_type; + * u32 pr_datasz; + * }; + * u8 pr_data[pr_datasz]; + * }[]; + */ + +#define BUF_SIZE (PAGE_SIZE / 4) + +struct gnu_property { + u32 pr_type; + u32 pr_datasz; +}; + +typedef bool (test_item_fn)(void *buf, u32 *arg, u32 type); +typedef void *(next_item_fn)(void *buf, u32 *arg, u32 type); + +static inline bool test_note_type(void *buf, u32 *align, u32 note_type) +{ + struct elf_note *n = buf; + + return ((n->n_type == note_type) && (n->n_namesz == 4) && + (memcmp(n + 1, "GNU", 4) == 0)); +} + +static inline void *next_note(void *buf, u32 *align, u32 note_type) +{ + struct elf_note *n = buf; + u64 size; + + if (check_add_overflow((u64)sizeof(*n), (u64)n->n_namesz, &size)) + return NULL; + + size = round_up(size, *align); + + if (check_add_overflow(size, (u64)n->n_descsz, &size)) + return NULL; + + size = round_up(size, *align); + + if (buf + size < buf) + return NULL; + else + return (buf + size); +} + +static inline bool test_property(void *buf, u32 *max_type, u32 pr_type) +{ + struct gnu_property *pr = buf; + + /* + * Property types must be in ascending order. + * Keep track of the max when testing each. + */ + if (pr->pr_type > *max_type) + *max_type = pr->pr_type; + + return (pr->pr_type == pr_type); +} + +static inline void *next_property(void *buf, u32 *max_type, u32 pr_type) +{ + struct gnu_property *pr = buf; + + if ((buf + sizeof(*pr) + pr->pr_datasz < buf) || + (pr->pr_type > pr_type) || + (pr->pr_type > *max_type)) + return NULL; + else + return (buf + sizeof(*pr) + pr->pr_datasz); +} + +/* + * Scan 'buf' for a pattern; return true if found. + * *pos is the distance from the beginning of buf to where + * the searched item or the next item is located. + */ +static int scan(u8 *buf, u32 buf_size, int item_size, test_item_fn test_item, + next_item_fn next_item, u32 *arg, u32 type, u32 *pos) +{ + int found = 0; + u8 *p, *max; + + max = buf + buf_size; + if (max < buf) + return 0; + + p = buf; + + while ((p + item_size < max) && (p + item_size > buf)) { + if (test_item(p, arg, type)) { + found = 1; + break; + } + + p = next_item(p, arg, type); + } + + *pos = (p + item_size <= buf) ? 0 : (u32)(p - buf); + return found; +} + +/* + * Search an NT_GNU_PROPERTY_TYPE_0 for the property of 'pr_type'. + */ +static int find_property(struct file *file, unsigned long desc_size, + loff_t file_offset, u8 *buf, + u32 pr_type, u32 *property) +{ + u32 buf_pos; + unsigned long read_size; + unsigned long done; + int found = 0; + int ret = 0; + u32 last_pr = 0; + + *property = 0; + buf_pos = 0; + + for (done = 0; done < desc_size; done += buf_pos) { + read_size = desc_size - done; + if (read_size > BUF_SIZE) + read_size = BUF_SIZE; + + ret = kernel_read(file, buf, read_size, &file_offset); + + if (ret != read_size) + return (ret < 0) ? ret : -EIO; + + ret = 0; + found = scan(buf, read_size, sizeof(struct gnu_property), + test_property, next_property, + &last_pr, pr_type, &buf_pos); + + if ((!buf_pos) || found) + break; + + file_offset += buf_pos - read_size; + } + + if (found) { + struct gnu_property *pr = + (struct gnu_property *)(buf + buf_pos); + + if (pr->pr_datasz == 4) { + u32 *max = (u32 *)(buf + read_size); + u32 *data = (u32 *)((u8 *)pr + sizeof(*pr)); + + if (data + 1 <= max) { + *property = *data; + } else { + file_offset += buf_pos - read_size; + file_offset += sizeof(*pr); + ret = kernel_read(file, property, 4, + &file_offset); + } + } + } + + return ret; +} + +/* + * Search a PT_NOTE segment for NT_GNU_PROPERTY_TYPE_0. + */ +static int find_note_type_0(struct file *file, loff_t file_offset, + unsigned long note_size, u32 align, + u32 pr_type, u32 *property) +{ + u8 *buf; + u32 buf_pos; + unsigned long read_size; + unsigned long done; + int found = 0; + int ret = 0; + + buf = kmalloc(BUF_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + *property = 0; + buf_pos = 0; + + for (done = 0; done < note_size; done += buf_pos) { + read_size = note_size - done; + if (read_size > BUF_SIZE) + read_size = BUF_SIZE; + + ret = kernel_read(file, buf, read_size, &file_offset); + + if (ret != read_size) { + ret = (ret < 0) ? ret : -EIO; + kfree(buf); + return ret; + } + + /* + * item_size = sizeof(struct elf_note) + elf_note.n_namesz. + * n_namesz is 4 for the note type we look for. + */ + ret = scan(buf, read_size, sizeof(struct elf_note) + 4, + test_note_type, next_note, + &align, NT_GNU_PROPERTY_TYPE_0, &buf_pos); + + file_offset += buf_pos - read_size; + + if (ret && !found) { + struct elf_note *n = + (struct elf_note *)(buf + buf_pos); + u64 start = round_up(sizeof(*n) + n->n_namesz, align); + u64 total = 0; + + if (check_add_overflow(start, (u64)n->n_descsz, &total)) { + ret = -EINVAL; + break; + } + total = round_up(total, align); + + ret = find_property(file, n->n_descsz, + file_offset + start, + buf, pr_type, property); + found++; + file_offset += total; + buf_pos += total; + } else if (!buf_pos || ret) { + ret = 0; + *property = 0; + break; + } + } + + kfree(buf); + return ret; +} + +/* + * Look at an ELF file's PT_NOTE segments, then NT_GNU_PROPERTY_TYPE_0, then + * the property of pr_type. + * + * Input: + * file: the file to search; + * phdr: the file's elf header; + * phnum: number of entries in phdr; + * pr_type: the property type. + * + * Output: + * The property found. + * + * Return: + * Zero or error. + */ +static int scan_segments_64(struct file *file, struct elf64_phdr *phdr, + int phnum, u32 pr_type, u32 *property) +{ + int i; + int err = 0; + + for (i = 0; i < phnum; i++, phdr++) { + if ((phdr->p_type != PT_NOTE) || (phdr->p_align != 8)) + continue; + + /* + * Search the PT_NOTE segment for NT_GNU_PROPERTY_TYPE_0. + */ + err = find_note_type_0(file, phdr->p_offset, phdr->p_filesz, + phdr->p_align, pr_type, property); + if (err) + return err; + } + + return 0; +} + +#ifdef CONFIG_COMPAT +static int scan_segments_32(struct file *file, struct elf32_phdr *phdr, + int phnum, u32 pr_type, u32 *property) +{ + int i; + int err = 0; + + for (i = 0; i < phnum; i++, phdr++) { + if ((phdr->p_type != PT_NOTE) || (phdr->p_align != 4)) + continue; + + /* + * Search the PT_NOTE segment for NT_GNU_PROPERTY_TYPE_0. + */ + err = find_note_type_0(file, phdr->p_offset, phdr->p_filesz, + phdr->p_align, pr_type, property); + if (err) + return err; + } + + return 0; +} +#endif + +int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f, + u32 pr_type, u32 *property) +{ + struct elf64_hdr *ehdr64 = ehdr_p; + int err = 0; + + *property = 0; + + if (ehdr64->e_ident[EI_CLASS] == ELFCLASS64) { + struct elf64_phdr *phdr64 = phdr_p; + + err = scan_segments_64(f, phdr64, ehdr64->e_phnum, + pr_type, property); + if (err < 0) + goto out; + } else { +#ifdef CONFIG_COMPAT + struct elf32_hdr *ehdr32 = ehdr_p; + + if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) { + struct elf32_phdr *phdr32 = phdr_p; + + err = scan_segments_32(f, phdr32, ehdr32->e_phnum, + pr_type, property); + if (err < 0) + goto out; + } +#else + WARN_ONCE(1, "Exec of 32-bit app, but CONFIG_COMPAT is not enabled.\n"); + return -ENOTSUPP; +#endif + } + +out: + return err; +} diff --git a/include/linux/elf.h b/include/linux/elf.h index e3649b3..c15febe 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -56,4 +56,16 @@ static inline int elf_coredump_extra_notes_write(struct coredump_params *cprm) { extern int elf_coredump_extra_notes_size(void); extern int elf_coredump_extra_notes_write(struct coredump_params *cprm); #endif + +#ifdef CONFIG_ARCH_USE_GNU_PROPERTY +extern int arch_setup_property(void *ehdr, void *phdr, struct file *f, + bool interp); +extern int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f, + u32 pr_type, u32 *feature); +#else +static inline int arch_setup_property(void *ehdr, void *phdr, struct file *f, + bool interp) { return 0; } +static inline int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f, + u32 pr_type, u32 *feature) { return 0; } +#endif #endif /* _LINUX_ELF_H */ diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index 34c02e4..7b7603a 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -372,6 +372,7 @@ typedef struct elf64_shdr { #define NT_PRFPREG 2 #define NT_PRPSINFO 3 #define NT_TASKSTRUCT 4 +#define NT_GNU_PROPERTY_TYPE_0 5 #define NT_AUXV 6 /* * Note to userspace developers: size of NT_SIGINFO note may increase @@ -443,4 +444,11 @@ typedef struct elf64_note { Elf64_Word n_type; /* Content type */ } Elf64_Nhdr; +/* .note.gnu.property types */ +#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) + #endif /* _UAPI_LINUX_ELF_H */ From patchwork Fri May 24 10:25:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 165096 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp3384280ili; Fri, 24 May 2019 03:26:29 -0700 (PDT) X-Google-Smtp-Source: APXvYqwrsKrJirzpgb5uM8LyyHG8RcjWmiNuHKnJ4O7GkNxh2wiNnfttUl+D11SKpZykBHQpemvI X-Received: by 2002:a17:90a:35c8:: with SMTP id r66mr8117478pjb.17.1558693588952; Fri, 24 May 2019 03:26:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558693588; cv=none; d=google.com; s=arc-20160816; b=ljW4GHRtFfPunCN3DL491r10NwcZULpdeL/EpSCitVLmOrdsHoCadA8YR87obLyrJD z9IuNTuN5jW3xyDGus3fJ65cYKELzh4hsNBrzCVtQCP591fQT6HBhsSpYbb41nstlp+H 5/8rO0pz9AT6nXDQwA7wJSHnFdgJZ55DN2WRPr8FaMwot3QCFfJUVuGLNkP4eeafaFM/ z1JYTpq1bm7+Ms7zk2nPmUjJ4V+fxCZeyIsjlWeW8Byrp3s+fohkvzdS+mdEOPBpDWu3 R4YrehJZEYpiwTFT5ZzQmdopV+8dccWoLggTuig7f+yJuSP7iRn7OC2T6BpMDDcJfVPg JI4g== 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=gAnGZLKcolQR2xRc+0cKmgQueAuvQi0/g8MQ74j3VXQ=; b=rUtDXoa1gtODZRSKQVPNSOoxkpl5goirvWb/uiJUXl3c78dSHGMqHasQcsIZqbq84O 6ICkxBvudkWNmcaTF67m6dcGgOxKZ28Ku9NyCngECT3mNIE0LiuCpaCaPkxPMVEdoBZt vvxPy0ikKNgukHdi8KvuShJfVClBODJRC+IAshsphdPF5lEbENtQF8qJ13R9zPq/dvZn 9ls5SbN61cTEP/cO5T+Mt9stcIEWTVz/2pav+qSDCroajsHfIwRLjOJA+rDZ20Z13M5R 87ulTtd1v/m7/5EWQEIg71qRyzxugrqlmjyzH/m5Pk0f2v5L03qlmtAbxoCqnsbXTrBr eNzQ== 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 q88si3646403pfa.250.2019.05.24.03.26.28; Fri, 24 May 2019 03:26:28 -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 S2390582AbfEXK01 (ORCPT + 30 others); Fri, 24 May 2019 06:26:27 -0400 Received: from foss.arm.com ([217.140.101.70]:39192 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389942AbfEXK00 (ORCPT ); Fri, 24 May 2019 06:26:26 -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 88B0215A2; Fri, 24 May 2019 03:26:26 -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 241723F703; Fri, 24 May 2019 03:26:24 -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 2/8] mm: Reserve asm-generic prot flag 0x10 for arch use Date: Fri, 24 May 2019 11:25:27 +0100 Message-Id: <1558693533-13465-3-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 The asm-generic mman definitions are used by a few architectures that also define an arch-specific PROT flag with value 0x10. This currently applies to sparc and powerpc, and arm64 will soon join in. To help future maintainers, document the use of this flag in the asm-generic header too. Signed-off-by: Dave Martin --- include/uapi/asm-generic/mman-common.h | 1 + 1 file changed, 1 insertion(+) -- 2.1.4 diff --git a/include/uapi/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h index abd238d..ad3c6e5 100644 --- a/include/uapi/asm-generic/mman-common.h +++ b/include/uapi/asm-generic/mman-common.h @@ -11,6 +11,7 @@ #define PROT_WRITE 0x2 /* page can be written */ #define PROT_EXEC 0x4 /* page can be executed */ #define PROT_SEM 0x8 /* page may be used for atomic ops */ + /* 0x10 reserved for arch-specific use */ #define PROT_NONE 0x0 /* page can not be accessed */ #define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ #define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ From patchwork Fri May 24 10:25:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 165097 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp3384309ili; Fri, 24 May 2019 03:26:31 -0700 (PDT) X-Google-Smtp-Source: APXvYqxYdhhD/fcVTfeM6rde95UZaAR4i9lxGaFPSHEqE6p5JFyyUIoyH5KEgCg12jzktp3N9a0x X-Received: by 2002:a17:90a:7305:: with SMTP id m5mr7770129pjk.84.1558693591146; Fri, 24 May 2019 03:26:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558693591; cv=none; d=google.com; s=arc-20160816; b=yIboMuU3fG52/PbS+4b5pFrLHzYzaTyuEy86EK2fb4F3eBMunBGCMtL/orwlI9Z48Y BGWixaZPRK9P93cRobLSA7YQD9KC96v02YW7nB7bjlq5m1LS3Q3xBaPKm14FBGIgUqET /ZsAnyiNDh3WBxqtpyPURbFyd0NVuKnjAG7CqpEDPVN5ohsL8sfXgRnkkTque0WiVeUC xEaRFFG0W81yqSYmMne1i2xuvpuqJ5BsYfqr4evAI7hAjV04JuK/2jl5ZnuFzdp5gRQz NEqoAaQqb9kE58eZ9n+mWt2/yOxASUu8LSnm+M1e5vbmFJdnkh8Kwe2XfxQFJzgx7+ld GuMg== 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=FjOtBNK6oBl35saagLiIhf4JEPC8nTkkPhPbJBv1nPc=; b=nNXa4uHVzdluh1wnng7UE2czVn2ysyVOf+iaXaMCPEDDqe7b7wspOAPZG0JIxfFY3u UWoQrGReL84S8fGzIVCIDPE80EC2FrpKOaM9SiVnwRqgj0zvck8dmGqsPdcGfg0aZ8YM ygRY5ybt4t80mWrMnCjOEsQSS3v5xyl8RS/0NXGBe+C8bGEcq9BRc/b13SY51OUVpVM1 4gQpdVgqRobg/0qVdLFUiQAspI2uPxNTDHyhnqzOwhIAwgMfZKsVyj/0Ra6OcNqnm/4w 0v7QtCqaYYKVRn0rVSWCAXzMg00T9KLJNHn3iQ5WcJsW2ZK0clsVYh8nDh3XxQETH1Fn swYA== 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 q88si3646403pfa.250.2019.05.24.03.26.30; Fri, 24 May 2019 03:26:31 -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 S2390606AbfEXK0a (ORCPT + 30 others); Fri, 24 May 2019 06:26:30 -0400 Received: from foss.arm.com ([217.140.101.70]:39210 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389942AbfEXK03 (ORCPT ); Fri, 24 May 2019 06:26:29 -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 0D5C31682; Fri, 24 May 2019 03:26:29 -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 C88693F703; Fri, 24 May 2019 03:26:26 -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 3/8] arm64: docs: cpu-feature-registers: Document ID_AA64PFR1_EL1 Date: Fri, 24 May 2019 11:25:28 +0100 Message-Id: <1558693533-13465-4-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 Commit d71be2b6c0e1 ("arm64: cpufeature: Detect SSBS and advertise to userspace") exposes ID_AA64PFR1_EL1 to userspace, but didn't update the documentation to match. Add it. Signed-off-by: Dave Martin --- Documentation/arm64/cpu-feature-registers.txt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) -- 2.1.4 diff --git a/Documentation/arm64/cpu-feature-registers.txt b/Documentation/arm64/cpu-feature-registers.txt index 684a0da..54d2bfa 100644 --- a/Documentation/arm64/cpu-feature-registers.txt +++ b/Documentation/arm64/cpu-feature-registers.txt @@ -160,7 +160,15 @@ infrastructure: x--------------------------------------------------x - 3) MIDR_EL1 - Main ID Register + 3) ID_AA64PFR1_EL1 - Processor Feature Register 1 + x--------------------------------------------------x + | Name | bits | visible | + |--------------------------------------------------| + | SSBS | [7-4] | y | + x--------------------------------------------------x + + + 4) MIDR_EL1 - Main ID Register x--------------------------------------------------x | Name | bits | visible | |--------------------------------------------------| @@ -179,7 +187,7 @@ infrastructure: as available on the CPU where it is fetched and is not a system wide safe value. - 4) ID_AA64ISAR1_EL1 - Instruction set attribute register 1 + 5) ID_AA64ISAR1_EL1 - Instruction set attribute register 1 x--------------------------------------------------x | Name | bits | visible | @@ -201,7 +209,7 @@ infrastructure: | DPB | [3-0] | y | x--------------------------------------------------x - 5) ID_AA64MMFR2_EL1 - Memory model feature register 2 + 6) ID_AA64MMFR2_EL1 - Memory model feature register 2 x--------------------------------------------------x | Name | bits | visible | @@ -209,7 +217,7 @@ infrastructure: | AT | [35-32] | y | x--------------------------------------------------x - 6) ID_AA64ZFR0_EL1 - SVE feature ID register 0 + 7) ID_AA64ZFR0_EL1 - SVE feature ID register 0 x--------------------------------------------------x | Name | bits | visible | From patchwork Fri May 24 10:25:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 165098 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp3384397ili; Fri, 24 May 2019 03:26:36 -0700 (PDT) X-Google-Smtp-Source: APXvYqznNslGceMgM9HD2C8uwzfBl0hfAKlPr5sYfRhd9jh/o0eEThNvJ5CTIv6c8poNCTcssk5+ X-Received: by 2002:a17:902:ba84:: with SMTP id k4mr4154563pls.55.1558693595884; Fri, 24 May 2019 03:26:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558693595; cv=none; d=google.com; s=arc-20160816; b=KCijkLwceVQ4GiU7S3IPhBTlkJbug4IKRTw/+B+wkQYgDNQqiSozuAQqdobhRiPwVD OGXs8A6nVBWYMPzcNhFYyqV3QQyVMq2dpKbOzS8YNgN7P7KKYYEMNW8i0Ik3ZJm7oVQu G/TbE0r4t4G9OirNqyWpP7Vh3lEzdIepvaZ5mUTFEBuhrCo7fYTtpRD4cQF77kV7TJkS Vkf/GWRiFaQJcUrSgQ+a0cOa1FbK2AHu9sMcpiteVHBz5vncEVXbgEulrLmUtYLYUpHn ujhDxf75610XTBZUQblCITkpS5MBIT1qv5DUvbdOJuTW/D8n8pvWTE5/LHbtnX78R56B WWjg== 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=axxSSvoHBVC+UREt+UdNHCbI8af7gD3qzZhyo5OeDLE=; b=PPUf1rvNnQ6ikNsUdUa1dpEuvElwQpCMpYVfgwYWbHIDD5xE/VBr8gQYm4sskb+CZy Xzyk6HuAA1qC1wDtAnhe/7mQcrpTzD18Ns+wmo1KhIUPQ/yCqNajoWv1imBWYmTX0M2O iNt8myIRvDXf06mZG+koN28DH0VzIgIoZPvT9hEgcsGJcE8d140Coa5faqipVwPGBAFz OlKs4j7PCHclEZGm42sefn7V60MjfzEuDQTyO5gA8/Pz76Mty8gEE18GUnvW3ld2w29v TmwT0YiYsFTxpNU46WoK7p73VKuRI4OKMjnh9tf86ztRjLqMQuPeq7kcEqEqtLgJsP3d saeA== 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 j9si1555748pfr.277.2019.05.24.03.26.35; Fri, 24 May 2019 03:26:35 -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 S2390628AbfEXK0e (ORCPT + 30 others); Fri, 24 May 2019 06:26:34 -0400 Received: from foss.arm.com ([217.140.101.70]:39230 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389942AbfEXK0c (ORCPT ); Fri, 24 May 2019 06:26:32 -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 868A215A2; Fri, 24 May 2019 03:26:31 -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 4D52A3F703; Fri, 24 May 2019 03:26:29 -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 4/8] arm64: Basic Branch Target Identification support Date: Fri, 24 May 2019 11:25:29 +0100 Message-Id: <1558693533-13465-5-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 This patch adds the bare minimum required to expose the ARMv8.5 Branch Target Identification feature to userspace. By itself, this does _not_ automatically enable BTI for any initial executable pages mapped by execve(). This will come later, but for now it should be possible to enable BTI manually on those pages by using mprotect() from within the target process. Other arches already using the generic mman.h are already using 0x10 for arch-specific prot flags, so we use that for PROT_BTI_GUARDED here. For consistency, signal handler entry points in BTI guarded pages are required to be annotated as such, just like any other function. This blocks a relatively minor attack vector, but comforming userspace will have the annotations anyway, so we may as well enforce them. Signed-off-by: Dave Martin --- Notes: * An #ifdef CONFIG_ARM64_BTI controls the cpufeature field visibility for userspace. It's probably best not to report BTI as present if the required kernel support is unavailable. * It's not clear whether anything extra needs to be done for hugepages. --- Documentation/arm64/cpu-feature-registers.txt | 2 ++ Documentation/arm64/elf_hwcaps.txt | 4 ++++ arch/arm64/Kconfig | 23 +++++++++++++++++++ arch/arm64/include/asm/cpucaps.h | 3 ++- arch/arm64/include/asm/cpufeature.h | 6 +++++ arch/arm64/include/asm/esr.h | 2 +- arch/arm64/include/asm/hwcap.h | 1 + arch/arm64/include/asm/mman.h | 33 +++++++++++++++++++++++++++ arch/arm64/include/asm/pgtable-hwdef.h | 1 + arch/arm64/include/asm/pgtable.h | 2 +- arch/arm64/include/asm/ptrace.h | 1 + arch/arm64/include/asm/sysreg.h | 2 ++ arch/arm64/include/uapi/asm/hwcap.h | 1 + arch/arm64/include/uapi/asm/mman.h | 9 ++++++++ arch/arm64/include/uapi/asm/ptrace.h | 1 + arch/arm64/kernel/cpufeature.c | 17 ++++++++++++++ arch/arm64/kernel/cpuinfo.c | 1 + arch/arm64/kernel/entry.S | 11 +++++++++ arch/arm64/kernel/ptrace.c | 2 +- arch/arm64/kernel/signal.c | 5 ++++ arch/arm64/kernel/syscall.c | 1 + arch/arm64/kernel/traps.c | 7 ++++++ include/linux/mm.h | 3 +++ 23 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 arch/arm64/include/asm/mman.h create mode 100644 arch/arm64/include/uapi/asm/mman.h -- 2.1.4 diff --git a/Documentation/arm64/cpu-feature-registers.txt b/Documentation/arm64/cpu-feature-registers.txt index 54d2bfa..602eb6e 100644 --- a/Documentation/arm64/cpu-feature-registers.txt +++ b/Documentation/arm64/cpu-feature-registers.txt @@ -165,6 +165,8 @@ infrastructure: | Name | bits | visible | |--------------------------------------------------| | SSBS | [7-4] | y | + |--------------------------------------------------| + | BT | [3-0] | y | x--------------------------------------------------x diff --git a/Documentation/arm64/elf_hwcaps.txt b/Documentation/arm64/elf_hwcaps.txt index b73a251..7a872d3 100644 --- a/Documentation/arm64/elf_hwcaps.txt +++ b/Documentation/arm64/elf_hwcaps.txt @@ -223,6 +223,10 @@ HWCAP_PACG ID_AA64ISAR1_EL1.GPI == 0b0001, as described by Documentation/arm64/pointer-authentication.txt. +HWCAP2_BTI + + Functionality implied by ID_AA64PFR0_EL1.BT == 0b0001. + 4. Unused AT_HWCAP bits ----------------------- diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 4780eb7..0f6765e 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1361,6 +1361,29 @@ config ARM64_PTR_AUTH endmenu +menu "ARMv8.5 architectural features" + +config ARM64_BTI + bool "Branch Target Identification support" + default y + help + Branch Target Identification (part of the ARMv8.5 Extensions) + provides a mechanism to limit the set of locations to which computed + branch instructions such as BR or BLR can jump. + + This is intended to provide complementary protection to other control + flow integrity protection mechanisms, such as the Pointer + authentication mechanism provided as part of the ARMv8.2 Extensions. + + To make use of BTI on CPUs that support it, say Y. + + Userspace binaries must also be specifically compiled to make use of + this mechanism. If you say N here or the hardware does not support + BTI, such binaries can still run, but you get no additional + enforcement of branch destinations. + +endmenu + config ARM64_SVE bool "ARM Scalable Vector Extension support" default y diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index defdc67..ccb44ae 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -62,7 +62,8 @@ #define ARM64_HAS_GENERIC_AUTH_IMP_DEF 41 #define ARM64_HAS_IRQ_PRIO_MASKING 42 #define ARM64_HAS_DCPODP 43 +#define ARM64_BTI 44 -#define ARM64_NCAPS 44 +#define ARM64_NCAPS 45 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index bc895c8..308cc54 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -617,6 +617,12 @@ static inline bool system_uses_irq_prio_masking(void) cpus_have_const_cap(ARM64_HAS_IRQ_PRIO_MASKING); } +static inline bool system_supports_bti(void) +{ + return IS_ENABLED(CONFIG_ARM64_BTI) && + cpus_have_const_cap(ARM64_BTI); +} + #define ARM64_SSBD_UNKNOWN -1 #define ARM64_SSBD_FORCE_DISABLE 0 #define ARM64_SSBD_KERNEL 1 diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 0e27fe9..0dd43a5 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -33,7 +33,7 @@ #define ESR_ELx_EC_PAC (0x09) /* EL2 and above */ /* Unallocated EC: 0x0A - 0x0B */ #define ESR_ELx_EC_CP14_64 (0x0C) -/* Unallocated EC: 0x0d */ +#define ESR_ELx_EC_BTI (0x0D) #define ESR_ELx_EC_ILL (0x0E) /* Unallocated EC: 0x0F - 0x10 */ #define ESR_ELx_EC_SVC32 (0x11) diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h index b4bfb66..c6b918f 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -95,6 +95,7 @@ #define KERNEL_HWCAP_SVEBITPERM __khwcap2_feature(SVEBITPERM) #define KERNEL_HWCAP_SVESHA3 __khwcap2_feature(SVESHA3) #define KERNEL_HWCAP_SVESM4 __khwcap2_feature(SVESM4) +#define KERNEL_HWCAP_BTI __khwcap2_feature(BTI) /* * This yields a mask that user programs can use to figure out what diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h new file mode 100644 index 0000000..a1f67aa --- /dev/null +++ b/arch/arm64/include/asm/mman.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_MMAN_H__ +#define __ASM_MMAN_H__ + +#include + +#define arch_calc_vm_prot_bits(prot, pkey) arm64_calc_vm_prot_bits(prot) +static inline unsigned long arm64_calc_vm_prot_bits(unsigned long prot) +{ + if (system_supports_bti() && (prot & PROT_BTI_GUARDED)) + return VM_ARM64_GP; + + return 0; +} + +#define arch_vm_get_page_prot(vm_flags) arm64_vm_get_page_prot(vm_flags) +static inline pgprot_t arm64_vm_get_page_prot(unsigned long vm_flags) +{ + return (vm_flags & VM_ARM64_GP) ? __pgprot(PTE_GP) : __pgprot(0); +} + +#define arch_validate_prot(prot, addr) arm64_validate_prot(prot, addr) +static inline int arm64_validate_prot(unsigned long prot, unsigned long addr) +{ + unsigned long supported = PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM; + + if (system_supports_bti()) + supported |= PROT_BTI_GUARDED; + + return (prot & ~supported) == 0; +} + +#endif /* ! __ASM_MMAN_H__ */ diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index a69259c..6e8af3a 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -162,6 +162,7 @@ #define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ #define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ #define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */ +#define PTE_GP (_AT(pteval_t, 1) << 50) /* BTI guarded */ #define PTE_DBM (_AT(pteval_t, 1) << 51) /* Dirty Bit Management */ #define PTE_CONT (_AT(pteval_t, 1) << 52) /* Contiguous range */ #define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 2c41b04..eefd9a44 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -640,7 +640,7 @@ static inline phys_addr_t pgd_page_paddr(pgd_t pgd) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | - PTE_PROT_NONE | PTE_VALID | PTE_WRITE; + PTE_PROT_NONE | PTE_VALID | PTE_WRITE | PTE_GP; /* preserve the hardware dirty information */ if (pte_hw_dirty(pte)) pte = pte_mkdirty(pte); diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index b2de329..b868ef11 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -41,6 +41,7 @@ /* Additional SPSR bits not exposed in the UABI */ #define PSR_IL_BIT (1 << 20) +#define PSR_BTYPE_CALL (2 << 10) /* AArch32-specific ptrace requests */ #define COMPAT_PTRACE_GETREGS 12 diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 902d75b..2b8d364 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -604,10 +604,12 @@ /* id_aa64pfr1 */ #define ID_AA64PFR1_SSBS_SHIFT 4 +#define ID_AA64PFR1_BT_SHIFT 0 #define ID_AA64PFR1_SSBS_PSTATE_NI 0 #define ID_AA64PFR1_SSBS_PSTATE_ONLY 1 #define ID_AA64PFR1_SSBS_PSTATE_INSNS 2 +#define ID_AA64PFR1_BT_BTI 0x1 /* id_aa64zfr0 */ #define ID_AA64ZFR0_SM4_SHIFT 40 diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h index 1a772b1..ea5bdda 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h @@ -63,5 +63,6 @@ #define HWCAP2_SVEBITPERM (1 << 4) #define HWCAP2_SVESHA3 (1 << 5) #define HWCAP2_SVESM4 (1 << 6) +#define HWCAP2_BTI (1 << 7) #endif /* _UAPI__ASM_HWCAP_H */ diff --git a/arch/arm64/include/uapi/asm/mman.h b/arch/arm64/include/uapi/asm/mman.h new file mode 100644 index 0000000..4776b43 --- /dev/null +++ b/arch/arm64/include/uapi/asm/mman.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI__ASM_MMAN_H +#define _UAPI__ASM_MMAN_H + +#include + +#define PROT_BTI_GUARDED 0x10 /* BTI guarded page */ + +#endif /* ! _UAPI__ASM_MMAN_H */ diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h index d78623a..e2361a1 100644 --- a/arch/arm64/include/uapi/asm/ptrace.h +++ b/arch/arm64/include/uapi/asm/ptrace.h @@ -46,6 +46,7 @@ #define PSR_I_BIT 0x00000080 #define PSR_A_BIT 0x00000100 #define PSR_D_BIT 0x00000200 +#define PSR_BTYPE_MASK 0x00000c00 #define PSR_SSBS_BIT 0x00001000 #define PSR_PAN_BIT 0x00400000 #define PSR_UAO_BIT 0x00800000 diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index ca27e08..0a6dbb3 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -182,6 +182,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = { ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SSBS_SHIFT, 4, ID_AA64PFR1_SSBS_PSTATE_NI), + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_BTI), + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_BT_SHIFT, 4, 0), ARM64_FTR_END, }; @@ -1558,6 +1560,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .min_field_value = 1, }, #endif +#ifdef CONFIG_ARM64_BTI + { + .desc = "Branch Target Identification", + .capability = ARM64_BTI, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = has_cpuid_feature, + .sys_reg = SYS_ID_AA64PFR1_EL1, + .field_pos = ID_AA64PFR1_BT_SHIFT, + .min_field_value = ID_AA64PFR1_BT_BTI, + .sign = FTR_UNSIGNED, + }, +#endif {}, }; @@ -1651,6 +1665,9 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4), #endif HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS), +#ifdef CONFIG_ARM64_BTI + HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI), +#endif #ifdef CONFIG_ARM64_PTR_AUTH HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, KERNEL_HWCAP_PACA), HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, KERNEL_HWCAP_PACG), diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index f6f7936..0fd3899 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -92,6 +92,7 @@ static const char *const hwcap_str[] = { "svebitperm", "svesha3", "svesm4", + "bti", NULL }; diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 1a7811b..da3694e 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -707,6 +707,8 @@ el0_sync: b.eq el0_sp_pc cmp x24, #ESR_ELx_EC_UNKNOWN // unknown exception in EL0 b.eq el0_undef + cmp x24, #ESR_ELx_EC_BTI // branch target exception + b.eq el0_bti cmp x24, #ESR_ELx_EC_BREAKPT_LOW // debug exception in EL0 b.ge el0_dbg b el0_inv @@ -851,6 +853,15 @@ el0_undef: mov x0, sp bl do_undefinstr b ret_to_user +el0_bti: + /* + * Branch target exception + */ + enable_daif + ct_user_exit + mov x0, sp + bl do_bti + b ret_to_user el0_sys: /* * System instructions, for trapped cache maintenance instructions diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index b82e0a9..3717b06 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -1860,7 +1860,7 @@ void syscall_trace_exit(struct pt_regs *regs) */ #define SPSR_EL1_AARCH64_RES0_BITS \ (GENMASK_ULL(63, 32) | GENMASK_ULL(27, 25) | GENMASK_ULL(23, 22) | \ - GENMASK_ULL(20, 13) | GENMASK_ULL(11, 10) | GENMASK_ULL(5, 5)) + GENMASK_ULL(20, 13) | GENMASK_ULL(5, 5)) #define SPSR_EL1_AARCH32_RES0_BITS \ (GENMASK_ULL(63, 32) | GENMASK_ULL(22, 22) | GENMASK_ULL(20, 20)) diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index a9b0485..2e540f5 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -741,6 +741,11 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, regs->regs[29] = (unsigned long)&user->next_frame->fp; regs->pc = (unsigned long)ka->sa.sa_handler; + if (system_supports_bti()) { + regs->pstate &= ~(regs->pstate & PSR_BTYPE_MASK); + regs->pstate |= PSR_BTYPE_CALL; + } + if (ka->sa.sa_flags & SA_RESTORER) sigtramp = ka->sa.sa_restorer; else diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 5610ac0..85b456b 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -66,6 +66,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, unsigned long flags = current_thread_info()->flags; regs->orig_x0 = regs->regs[0]; + regs->pstate &= ~(regs->pstate & PSR_BTYPE_MASK); regs->syscallno = scno; local_daif_restore(DAIF_PROCCTX); diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index ade3204..079ce1a 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -426,6 +426,12 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc); } +asmlinkage void __exception do_bti(struct pt_regs *regs) +{ + BUG_ON(!user_mode(regs)); + force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc); +} + #define __user_cache_maint(insn, address, res) \ if (address >= user_addr_max()) { \ res = -EFAULT; \ @@ -756,6 +762,7 @@ static const char *esr_class_str[] = { [ESR_ELx_EC_FP_ASIMD] = "ASIMD", [ESR_ELx_EC_CP10_ID] = "CP10 MRC/VMRS", [ESR_ELx_EC_CP14_64] = "CP14 MCRR/MRRC", + [ESR_ELx_EC_BTI] = "BTI", [ESR_ELx_EC_ILL] = "PSTATE.IL", [ESR_ELx_EC_SVC32] = "SVC (AArch32)", [ESR_ELx_EC_HVC32] = "HVC (AArch32)", diff --git a/include/linux/mm.h b/include/linux/mm.h index 0e8834a..639dc54 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -318,6 +318,9 @@ extern unsigned int kobjsize(const void *objp); #elif defined(CONFIG_SPARC64) # define VM_SPARC_ADI VM_ARCH_1 /* Uses ADI tag for access control */ # define VM_ARCH_CLEAR VM_SPARC_ADI +#elif defined(CONFIG_ARM64) +# define VM_ARM64_GP VM_ARCH_1 /* BTI guarded page */ +# define VM_ARCH_CLEAR VM_ARM64_GP #elif !defined(CONFIG_MMU) # define VM_MAPPED_COPY VM_ARCH_1 /* T if mapped copy of data (nommu mmap) */ #endif From patchwork Fri May 24 10:25:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 165099 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp3384422ili; Fri, 24 May 2019 03:26:38 -0700 (PDT) X-Google-Smtp-Source: APXvYqyotECtRplg+TJfjGBq3020u/0FtI3inGAlu95bpfkWAdK7uOjz7IB1K0uPoL8Zbz9Ha2Lb X-Received: by 2002:a65:44c8:: with SMTP id g8mr105129626pgs.443.1558693598380; Fri, 24 May 2019 03:26:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558693598; cv=none; d=google.com; s=arc-20160816; b=eXwP3P8OIm3qzCe5xhaMSOb8ve9nM0jlpA2PuZRSfoGbdE9UcdmKr/0QvtFPeXUnTB SKK26MF0MUSUUEhQGBvsGEcmQSNNrKvrbldFRmsg4cehVRfSi4qLYGkyl7pTeu0EeRza oQHQg3eUOzGcUikCnqa2vOf2jcDgbejGeUBbmQm0jmSyM7GQIooGpLl/xrZbFLyQ3jTO 38HiVF+8ij5a9PJRxu/OtG7vniQzVd1CeRbwF2ZDX9qugdpssU60Zru9ix1atCOnLoPH j1BC+wuag/qHXgoppEsidtj5D855B4HsVo5GDpowlGvOn6epaUExxuB0amQfFeW8UaQm 8Lww== 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=BlycG0574qiXJdoumfo+t//Focf5kb7xLLxTSPGtB34=; b=HwsidPLO40dr6bCVB0Vj5M4qNn7eApQbgYES9EjhFDjqbIzGH2Uep5b7f+isaQmELO wrO8R4VqbwYQaA8RXMAe0j3Z0eOB20IqJM+E6Q0SjWsyT2k5mL60R2bDe4OcF6reKsFn 5+PC1BeRcsanD8oI89yXF9n5RaI7ln/zwoPow3XNNHQhj7ZdIpGDqShLmslu75917BFc mNbMAlNh8c2OI3L1m6Axy9+EcM4I1FsnypWHGwkTSRseETSvcjo7qHtJCHhwPG3jIhyA M90wE05P+ybBuCZHcVt7lxDr2yOHQ5dnhXWlr2r1o49daHaUJi26Aa3nPPbSZe9L61LQ E4kw== 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 j9si1555748pfr.277.2019.05.24.03.26.38; Fri, 24 May 2019 03:26:38 -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 S2390651AbfEXK0h (ORCPT + 30 others); Fri, 24 May 2019 06:26:37 -0400 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:39254 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390631AbfEXK0e (ORCPT ); Fri, 24 May 2019 06:26:34 -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 0E3541682; Fri, 24 May 2019 03:26:34 -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 C9DF43F703; Fri, 24 May 2019 03:26:31 -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 5/8] elf: Parse program properties before destroying the old process Date: Fri, 24 May 2019 11:25:30 +0100 Message-Id: <1558693533-13465-6-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 Currently we try to read program properties from NT_GNU_PROPERTY_TYPE_0 ELF notes. However, we do this too late to either report failures cleanly or influence certain aspects of process setup such as the default mmap permissions for the new executable's pages (which will matter for arm64 for example). So, split parsing of the notes from use: rename arch_setup_property() to arch_parse_property() to make the intent clear, and hoist it before flush_old_exec() so that we can still bail out gracefully if needed. Also propagate arch_state into the call so that the arch backend has somewhere to stash information for later use. Signed-off-by: Dave Martin --- fs/binfmt_elf.c | 26 +++++++++++++------------- include/linux/elf.h | 15 +++++++++++---- 2 files changed, 24 insertions(+), 17 deletions(-) -- 2.1.4 diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 18015fc..32c9c13 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -851,6 +851,19 @@ static int load_elf_binary(struct linux_binprm *bprm) } } + if (interpreter) { + retval = arch_parse_property(&loc->interp_elf_ex, + interp_elf_phdata, + interpreter, true, &arch_state); + } else { + retval = arch_parse_property(&loc->elf_ex, + elf_phdata, + bprm->file, false, &arch_state); + } + + if (retval < 0) + goto out_free_dentry; + /* * Allow arch code to reject the ELF at this point, whilst it's * still possible to return an error to the code that invoked @@ -1080,19 +1093,6 @@ static int load_elf_binary(struct linux_binprm *bprm) } if (interpreter) { - retval = arch_setup_property(&loc->interp_elf_ex, - interp_elf_phdata, - interpreter, true); - } else { - retval = arch_setup_property(&loc->elf_ex, - elf_phdata, - bprm->file, false); - } - - if (retval < 0) - goto out_free_dentry; - - if (interpreter) { unsigned long interp_map_addr = 0; elf_entry = load_elf_interp(&loc->interp_elf_ex, diff --git a/include/linux/elf.h b/include/linux/elf.h index c15febe..cfcf154 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -57,14 +57,21 @@ extern int elf_coredump_extra_notes_size(void); extern int elf_coredump_extra_notes_write(struct coredump_params *cprm); #endif +struct arch_elf_state; + #ifdef CONFIG_ARCH_USE_GNU_PROPERTY -extern int arch_setup_property(void *ehdr, void *phdr, struct file *f, - bool interp); +extern int arch_parse_property(void *ehdr, void *phdr, struct file *f, + bool interp, struct arch_elf_state *arch_state); extern int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f, u32 pr_type, u32 *feature); #else -static inline int arch_setup_property(void *ehdr, void *phdr, struct file *f, - bool interp) { return 0; } +static inline int arch_parse_property(void *ehdr, void *phdr, struct file *f, + bool interp, + struct arch_elf_state *arch_state) +{ + return 0; +} + static inline int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f, u32 pr_type, u32 *feature) { return 0; } #endif From patchwork Fri May 24 10:25:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 165100 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp3384453ili; Fri, 24 May 2019 03:26:40 -0700 (PDT) X-Google-Smtp-Source: APXvYqxN0C0VVdbhWxeVrzJEvu/g9l9K3+xguTIYDXc5XVIChsVCEdHUiuSjUIavHVSKBW3XwXww X-Received: by 2002:a17:90a:9dc1:: with SMTP id x1mr8154853pjv.102.1558693600424; Fri, 24 May 2019 03:26:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558693600; cv=none; d=google.com; s=arc-20160816; b=XncFQH6xZB9qifCnfqYEcB2ZYvrTkr13ZsYPiuJNCMHXhH1lzluDhMOgFof6hVzNyE t/x+PuN2+pSSC1/3dQ5G/iivM6789KNYpB6B2wZSdEmBz17WwJZwl+yYWyPGW15MTzeD G0B/xXB3TI2SmI5wOS3gcAPenwpvPEu3klcTY1hglU5pp5DYlqbUCrma5fdQoJAPfANt nAPe70bJS/OujhbOILKW8ka4sqVimCMWSix6ASL1uGLX8CDvtHgWDOBH0zY02Lay/BS6 HWVg+b6KpMq4yKX8x6HtA82jddsqP+OMcc2aGexQU07YrQSwEBZVivLPuxRO7JJYK+EW 5aPQ== 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=1vDOa7IEF4qL1731CTsOqFrOF2Up5ySHkEB9xGhHr7U=; b=E4gqYquXN2t3/aTP2xbmXTcy2O5Fvpfz1ny5+4iKaE+oP+9y0Lw1Ksl1HWrk7YGp8n 53kdw7cbhW8bLqamw3Rh4b8uRTSibSBisQ1Dk2YC0Hxuw0EZEPxwn+IwzbVi+uY9MB/S +yUW55sPBk0fMFx5nmqnXufsEUUzD8ETl8ln9MNOEzY96qR0137fp9DowyqLbYA8vkSm TxbR2IhHQivYKFicjjM6Ix8sAwx7GpHZT2ErxVCUB83k/XbUaV6/ftlkVgtAADRNeQcZ KDf85NuhGF092tiw+Wa+/OE+V7Dl0Pc0d/59TQhoCwU5udvZ38d7es1y6h1l39sXHwuk JfZQ== 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.40; Fri, 24 May 2019 03:26:40 -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 S2390670AbfEXK0j (ORCPT + 30 others); Fri, 24 May 2019 06:26:39 -0400 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:39272 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390649AbfEXK0h (ORCPT ); Fri, 24 May 2019 06:26:37 -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 8939DA78; Fri, 24 May 2019 03:26:36 -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 4E3FF3F703; Fri, 24 May 2019 03:26:34 -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 6/8] elf: Allow arch to tweak initial mmap prot flags Date: Fri, 24 May 2019 11:25:31 +0100 Message-Id: <1558693533-13465-7-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 An arch may want to tweak the mmap prot flags for an ELF executable's initial mappings. For example, arm64 is going to need to add PROT_BTI_GUARDED for executable pages in an ELF process whose executable is marked as using Branch Target Identification (an ARMv8.5-A control flow integrity feature). So that this can be done in a generic way, add a hook arch_elf_adjust_prot() to modify the prot flags as desired: arches can select CONFIG_HAVE_ELF_PROT and implement their own backend where necessary. By default, leave the prot flags unchanged. Signed-off-by: Dave Martin --- fs/Kconfig.binfmt | 3 +++ fs/binfmt_elf.c | 18 ++++++++++++------ include/linux/elf.h | 13 +++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) -- 2.1.4 diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 175a1f5..cd3d315 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt @@ -35,6 +35,9 @@ config COMPAT_BINFMT_ELF config ARCH_BINFMT_ELF_STATE bool +config ARCH_HAVE_ELF_PROT + bool + config ARCH_USE_GNU_PROPERTY bool depends on 64BIT diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 32c9c13..3d88dcc 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -524,7 +524,8 @@ static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp, #endif /* !CONFIG_ARCH_BINFMT_ELF_STATE */ -static inline int make_prot(u32 p_flags) +static inline int make_prot(u32 p_flags, struct arch_elf_state *arch_state, + bool has_interp, bool is_interp) { int prot = 0; @@ -534,7 +535,8 @@ static inline int make_prot(u32 p_flags) prot |= PROT_WRITE; if (p_flags & PF_X) prot |= PROT_EXEC; - return prot; + + return arch_elf_adjust_prot(prot, arch_state, has_interp, is_interp); } /* This is much more generalized than the library routine read function, @@ -544,7 +546,8 @@ static inline int make_prot(u32 p_flags) static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, struct file *interpreter, unsigned long *interp_map_addr, - unsigned long no_base, struct elf_phdr *interp_elf_phdata) + unsigned long no_base, struct elf_phdr *interp_elf_phdata, + struct arch_elf_state *arch_state) { struct elf_phdr *eppnt; unsigned long load_addr = 0; @@ -576,7 +579,8 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { if (eppnt->p_type == PT_LOAD) { int elf_type = MAP_PRIVATE | MAP_DENYWRITE; - int elf_prot = make_prot(eppnt->p_flags); + int elf_prot = make_prot(eppnt->p_flags, arch_state, + true, true); unsigned long vaddr = 0; unsigned long k, map_addr; @@ -952,7 +956,8 @@ static int load_elf_binary(struct linux_binprm *bprm) elf_fixed = MAP_FIXED; } - elf_prot = make_prot(elf_ppnt->p_flags); + elf_prot = make_prot(elf_ppnt->p_flags, &arch_state, + !!interpreter, false); elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE; @@ -1098,7 +1103,8 @@ static int load_elf_binary(struct linux_binprm *bprm) elf_entry = load_elf_interp(&loc->interp_elf_ex, interpreter, &interp_map_addr, - load_bias, interp_elf_phdata); + load_bias, interp_elf_phdata, + &arch_state); if (!IS_ERR((void *)elf_entry)) { /* * load_elf_interp() returns relocation diff --git a/include/linux/elf.h b/include/linux/elf.h index cfcf154..2057187 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -75,4 +75,17 @@ static inline int arch_parse_property(void *ehdr, void *phdr, struct file *f, static inline int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f, u32 pr_type, u32 *feature) { return 0; } #endif + +#ifdef CONFIG_ARCH_HAVE_ELF_PROT +int arch_elf_adjust_prot(int prot, const struct arch_elf_state *state, + bool has_interp, bool is_interp); +#else +static inline int arch_elf_adjust_prot(int prot, + const struct arch_elf_state *state, + bool has_interp, bool is_interp) +{ + return prot; +} +#endif + #endif /* _LINUX_ELF_H */ 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 */ From patchwork Fri May 24 10:25:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 165102 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp3384551ili; Fri, 24 May 2019 03:26:45 -0700 (PDT) X-Google-Smtp-Source: APXvYqwvQpCuDYDww/4AeOcmwnCHyTT7LCnlN6EfilyEfKQx8Ptub9SsyTqd+zNv3WnblCrHvVh/ X-Received: by 2002:a63:e645:: with SMTP id p5mr103812838pgj.4.1558693605803; Fri, 24 May 2019 03:26:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558693605; cv=none; d=google.com; s=arc-20160816; b=jjt5ZBqNiGhqot+TQ0g4GZ6uLZ4l1LhY1L7i5Sc/MMS4E4ZzSwow99cqgo6pN1GbAt zfu0lsKOF9rpdm+9JXcY5aBQpIrSG1p2E6GL+Cc8D2nOrWdCXEoogf2m6BSxTkkzfKNh X8KR04jzlTBa6xcuLtSS8NWBugWfiyFY3S/6+zzmYVsHxgFr4Ifl3XPtx8ZjFZGNcxxa eBCKVZn4Kj5hEO4UJ3kWXYRe3XzKNrGe8JVFurGNiVAZKabegp0hSRRkTipO+0cmyzxb M6mZpzCQ6ACv4YZUY7t91vQNHEwnjq/sNSjSuyRVWdes7xQ8sj9GTK47Tv7yx8XX01Sx kDkQ== 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=PR9MnhVr1aYy+Ys3/ZdiAx07GuT/CLOTijM0XW4sbbQ=; b=LkGi+bYfMAkU/siwxyFP3OOzub2cPLBT9B6jomUVZUakBKPPxKmOi0radQE58QPThp EdSZnLDO09fU2QH7vJdGXXwkNPcBRuYGy6Lvl247T5QO8tjgoikiy8H9mezQlL71VBb1 mSJGEEaX0y1uguWSS2/hZ30203dhA9LvBOqXrQLoc10xD0mI+/ZWMYw7HPxN9+DS5yCN pZUxiMh2xIs2HEM/eSMhSE6VSlUz1Ej4HO3GQAeYy5vZxSem1rZigiwx5EtG2K2vH5GT mj/+3oJzXRH1J/5HLdMQ5gW/peSfUjJuEQEvcM/z0hyJOCKlZUvJ8rXWqAiLvlrO/56d dykw== 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.45; Fri, 24 May 2019 03:26:45 -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 S2390721AbfEXK0o (ORCPT + 30 others); Fri, 24 May 2019 06:26:44 -0400 Received: from foss.arm.com ([217.140.101.70]:39318 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390672AbfEXK0m (ORCPT ); Fri, 24 May 2019 06:26:42 -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 867CFA78; Fri, 24 May 2019 03:26:41 -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 4DEF03F703; Fri, 24 May 2019 03:26:39 -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 8/8] arm64: BTI: Decode BYTPE bits when printing PSTATE Date: Fri, 24 May 2019 11:25:33 +0100 Message-Id: <1558693533-13465-9-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 The current code to print PSTATE symbolically when generating backtraces etc., does not include the BYTPE field used by Branch Target Identification. So, decode BYTPE and print it too. In the interests of human-readability, print the classes of BTI matched. The symbolic motation, BYTPE (PSTATE[11:10]) and permitted classes of subsequent instruction are: -- (BTYPE=0b00): any insn jc (BTYPE=0b01): BTI jc, BTI j, BTI c, PACIxSP -c (BYTPE=0b10): BTI jc, BTI c, PACIxSP j- (BTYPE=0b11): BTI jc, BTI j Signed-off-by: Dave Martin --- arch/arm64/include/asm/ptrace.h | 4 +++- arch/arm64/kernel/process.c | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) -- 2.1.4 diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index b868ef11..f91e51c 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -40,8 +40,10 @@ #define GIC_PRIO_IRQOFF (GIC_PRIO_IRQON & ~0x80) /* Additional SPSR bits not exposed in the UABI */ +#define PSR_BTYPE_SHIFT 10 + #define PSR_IL_BIT (1 << 20) -#define PSR_BTYPE_CALL (2 << 10) +#define PSR_BTYPE_CALL (2 << PSR_BTYPE_SHIFT) /* AArch32-specific ptrace requests */ #define COMPAT_PTRACE_GETREGS 12 diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 104b0d8..dde5c40 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -236,7 +236,11 @@ static void print_pstate(struct pt_regs *regs) pstate & PSR_AA32_I_BIT ? 'I' : 'i', pstate & PSR_AA32_F_BIT ? 'F' : 'f'); } else { - printk("pstate: %08llx (%c%c%c%c %c%c%c%c %cPAN %cUAO)\n", + static const char *const btypes[] = { "--", "jc", "-c", "j-" }; + const char *btype_str = btypes[(pstate & PSR_BTYPE_MASK) >> + PSR_BTYPE_SHIFT]; + + printk("pstate: %08llx (%c%c%c%c %c%c%c%c %cPAN %cUAO BTYPE=%s)\n", pstate, pstate & PSR_N_BIT ? 'N' : 'n', pstate & PSR_Z_BIT ? 'Z' : 'z', @@ -247,7 +251,8 @@ static void print_pstate(struct pt_regs *regs) pstate & PSR_I_BIT ? 'I' : 'i', pstate & PSR_F_BIT ? 'F' : 'f', pstate & PSR_PAN_BIT ? '+' : '-', - pstate & PSR_UAO_BIT ? '+' : '-'); + pstate & PSR_UAO_BIT ? '+' : '-', + btype_str); } }