Module Name: src
Committed By: maxv
Date: Mon Apr 13 05:40:26 UTC 2020
Modified Files:
src/sys/arch/aarch64/aarch64: aarch64_machdep.c cpuswitch.S pmap.c
pmapboot.c trap.c vectors.S
src/sys/arch/aarch64/conf: Makefile.aarch64
src/sys/arch/arm/conf: files.arm
src/sys/arch/arm/include: asm.h
src/sys/arch/evbarm/conf: GENERIC64
Log Message:
Add support for Branch Target Identification (BTI).
On the executable pages that have the GP (Guarded Page) bit, the semantic
of the "br" and "blr" instructions is changed: the CPU expects the first
instruction of the jump/call target to be "bti", and faults if it isn't.
We add the GP bit on the kernel .text pages (and incidentally the .rodata
pages, but we don't care). The compiler adds a "bti c" instruction at the
beginning of each C function. We modify the ENTRY() macros to manually add
"bti c" in the asm functions.
cpuswitch.S needs a specific change: with "br x27" the CPU expects "bti j",
which is bad because the functions begin with "bti c"; switch to "br x16",
for the CPU to accept "bti c".
BTI helps defend against JOP/COP. Tested on Qemu.
To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/sys/arch/aarch64/aarch64/aarch64_machdep.c
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/aarch64/aarch64/cpuswitch.S
cvs rdiff -u -r1.69 -r1.70 src/sys/arch/aarch64/aarch64/pmap.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/aarch64/aarch64/pmapboot.c
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/aarch64/aarch64/trap.c
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/aarch64/aarch64/vectors.S
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/aarch64/conf/Makefile.aarch64
cvs rdiff -u -r1.154 -r1.155 src/sys/arch/arm/conf/files.arm
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/arm/include/asm.h
cvs rdiff -u -r1.150 -r1.151 src/sys/arch/evbarm/conf/GENERIC64
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/aarch64/aarch64/aarch64_machdep.c
diff -u src/sys/arch/aarch64/aarch64/aarch64_machdep.c:1.41 src/sys/arch/aarch64/aarch64/aarch64_machdep.c:1.42
--- src/sys/arch/aarch64/aarch64/aarch64_machdep.c:1.41 Sun Apr 12 07:49:58 2020
+++ src/sys/arch/aarch64/aarch64/aarch64_machdep.c Mon Apr 13 05:40:25 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: aarch64_machdep.c,v 1.41 2020/04/12 07:49:58 maxv Exp $ */
+/* $NetBSD: aarch64_machdep.c,v 1.42 2020/04/13 05:40:25 maxv Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,9 +30,10 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.41 2020/04/12 07:49:58 maxv Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.42 2020/04/13 05:40:25 maxv Exp $");
#include "opt_arm_debug.h"
+#include "opt_cpuoptions.h"
#include "opt_ddb.h"
#include "opt_kernhist.h"
#include "opt_modular.h"
@@ -112,6 +113,24 @@ uint32_t dumpmag = 0x8fca0101; /* magic
int dumpsize = 0; /* also for savecore */
long dumplo = 0;
+int aarch64_bti_enabled __read_mostly;
+
+static void
+bti_init(void)
+{
+#ifdef ARMV85_BTI
+ extern uint64_t pmap_attr_gp;
+ uint64_t reg;
+
+ reg = reg_id_aa64pfr1_el1_read();
+
+ if (reg >= ID_AA64PFR1_EL1_BT_SUPPORTED) {
+ pmap_attr_gp = LX_BLKPAG_GP;
+ aarch64_bti_enabled = 1;
+ }
+#endif
+}
+
void
cpu_kernel_vm_init(uint64_t memory_start __unused, uint64_t memory_size __unused)
{
@@ -121,6 +140,8 @@ cpu_kernel_vm_init(uint64_t memory_start
extern char __rodata_start[];
u_int blk;
+ bti_init();
+
vaddr_t kernstart = trunc_page((vaddr_t)__kernel_text);
vaddr_t kernend = round_page((vaddr_t)_end);
paddr_t kernstart_phys = KERN_VTOPHYS(kernstart);
@@ -464,6 +485,14 @@ SYSCTL_SETUP(sysctl_machdep_setup, "sysc
NULL, 0,
&aarch64_pac_enabled, 0,
CTL_MACHDEP, CTL_CREATE, CTL_EOL);
+
+ sysctl_createv(clog, 0, NULL, NULL,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_INT, "bti",
+ SYSCTL_DESCR("Whether Branch Target Identification is enabled"),
+ NULL, 0,
+ &aarch64_bti_enabled, 0,
+ CTL_MACHDEP, CTL_CREATE, CTL_EOL);
}
void
Index: src/sys/arch/aarch64/aarch64/cpuswitch.S
diff -u src/sys/arch/aarch64/aarch64/cpuswitch.S:1.16 src/sys/arch/aarch64/aarch64/cpuswitch.S:1.17
--- src/sys/arch/aarch64/aarch64/cpuswitch.S:1.16 Sun Apr 12 07:49:58 2020
+++ src/sys/arch/aarch64/aarch64/cpuswitch.S Mon Apr 13 05:40:25 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuswitch.S,v 1.16 2020/04/12 07:49:58 maxv Exp $ */
+/* $NetBSD: cpuswitch.S,v 1.17 2020/04/13 05:40:25 maxv Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
#include "opt_ddb.h"
#include "opt_kasan.h"
-RCSID("$NetBSD: cpuswitch.S,v 1.16 2020/04/12 07:49:58 maxv Exp $")
+RCSID("$NetBSD: cpuswitch.S,v 1.17 2020/04/13 05:40:25 maxv Exp $")
ARMV8_DEFINE_OPTIONS
@@ -262,7 +262,8 @@ ENTRY_NP(lwp_trampoline)
*/
adr x30, el0_trap_exit /* tail call via lr */
mov x0, x28 /* mov arg into place */
- br x27 /* call function with arg */
+ mov x16, x27 /* use x16 as jump register, for BTI */
+ br x16 /* call function with arg */
END(lwp_trampoline)
.macro unwind_x0_x2
Index: src/sys/arch/aarch64/aarch64/pmap.c
diff -u src/sys/arch/aarch64/aarch64/pmap.c:1.69 src/sys/arch/aarch64/aarch64/pmap.c:1.70
--- src/sys/arch/aarch64/aarch64/pmap.c:1.69 Wed Apr 8 00:13:40 2020
+++ src/sys/arch/aarch64/aarch64/pmap.c Mon Apr 13 05:40:25 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.69 2020/04/08 00:13:40 ryo Exp $ */
+/* $NetBSD: pmap.c,v 1.70 2020/04/13 05:40:25 maxv Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.69 2020/04/08 00:13:40 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.70 2020/04/13 05:40:25 maxv Exp $");
#include "opt_arm_debug.h"
#include "opt_ddb.h"
@@ -221,6 +221,8 @@ bool pmap_devmap_bootstrap_done = false;
static struct pool_cache _pmap_cache;
static struct pool_cache _pmap_pv_pool;
+/* Set to LX_BLKPAG_GP if supported. */
+uint64_t pmap_attr_gp = 0;
static inline void
pmap_pv_lock(struct pmap_page *pp)
Index: src/sys/arch/aarch64/aarch64/pmapboot.c
diff -u src/sys/arch/aarch64/aarch64/pmapboot.c:1.6 src/sys/arch/aarch64/aarch64/pmapboot.c:1.7
--- src/sys/arch/aarch64/aarch64/pmapboot.c:1.6 Sat Feb 29 21:34:37 2020
+++ src/sys/arch/aarch64/aarch64/pmapboot.c Mon Apr 13 05:40:25 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: pmapboot.c,v 1.6 2020/02/29 21:34:37 ryo Exp $ */
+/* $NetBSD: pmapboot.c,v 1.7 2020/04/13 05:40:25 maxv Exp $ */
/*
* Copyright (c) 2018 Ryo Shimizu <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmapboot.c,v 1.6 2020/02/29 21:34:37 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmapboot.c,v 1.7 2020/04/13 05:40:25 maxv Exp $");
#include "opt_arm_debug.h"
#include "opt_ddb.h"
@@ -50,11 +50,14 @@ __KERNEL_RCSID(0, "$NetBSD: pmapboot.c,v
static void
pmapboot_protect_entry(pt_entry_t *pte, vm_prot_t clrprot)
{
+ extern uint64_t pmap_attr_gp;
+
if (clrprot & VM_PROT_READ)
*pte &= ~LX_BLKPAG_AF;
if (clrprot & VM_PROT_WRITE) {
*pte &= ~LX_BLKPAG_AP;
*pte |= LX_BLKPAG_AP_RO;
+ *pte |= pmap_attr_gp;
}
if (clrprot & VM_PROT_EXECUTE)
*pte |= LX_BLKPAG_UXN|LX_BLKPAG_PXN;
Index: src/sys/arch/aarch64/aarch64/trap.c
diff -u src/sys/arch/aarch64/aarch64/trap.c:1.26 src/sys/arch/aarch64/aarch64/trap.c:1.27
--- src/sys/arch/aarch64/aarch64/trap.c:1.26 Thu Feb 20 12:15:33 2020
+++ src/sys/arch/aarch64/aarch64/trap.c Mon Apr 13 05:40:25 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.26 2020/02/20 12:15:33 rin Exp $ */
+/* $NetBSD: trap.c,v 1.27 2020/04/13 05:40:25 maxv Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.26 2020/02/20 12:15:33 rin Exp $");
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.27 2020/04/13 05:40:25 maxv Exp $");
#include "opt_arm_intr_impl.h"
#include "opt_compat_netbsd32.h"
@@ -238,6 +238,7 @@ trap_el1h_sync(struct trapframe *tf)
case ESR_EC_PC_ALIGNMENT:
case ESR_EC_SP_ALIGNMENT:
case ESR_EC_ILL_STATE:
+ case ESR_EC_BTE_A64:
default:
panic("Trap: fatal %s: pc=%016" PRIx64 " sp=%016" PRIx64
" esr=%08x", eclass_trapname(eclass), tf->tf_pc, tf->tf_sp,
Index: src/sys/arch/aarch64/aarch64/vectors.S
diff -u src/sys/arch/aarch64/aarch64/vectors.S:1.13 src/sys/arch/aarch64/aarch64/vectors.S:1.14
--- src/sys/arch/aarch64/aarch64/vectors.S:1.13 Sun Apr 12 07:49:58 2020
+++ src/sys/arch/aarch64/aarch64/vectors.S Mon Apr 13 05:40:25 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: vectors.S,v 1.13 2020/04/12 07:49:58 maxv Exp $ */
+/* $NetBSD: vectors.S,v 1.14 2020/04/13 05:40:25 maxv Exp $ */
#include <aarch64/asm.h>
#include "assym.h"
@@ -23,7 +23,7 @@
* Template for the handler functions.
*/
.macro vector_func, func, el, label, tpidr
-ENTRY_NP(\func)
+ENTRY_NBTI(\func)
.align 7 /* cacheline-aligned */
.if \el == 1
@@ -143,7 +143,7 @@ vector_func el0_32error_handler, 0, trap
* The vector table. Must be aligned to 2048.
*/
.align 11
-ENTRY_NP(el1_vectors)
+ENTRY_NBTI(el1_vectors)
/*
* Exception taken from current Exception Level with SP_EL0.
* (These shouldn't happen)
Index: src/sys/arch/aarch64/conf/Makefile.aarch64
diff -u src/sys/arch/aarch64/conf/Makefile.aarch64:1.18 src/sys/arch/aarch64/conf/Makefile.aarch64:1.19
--- src/sys/arch/aarch64/conf/Makefile.aarch64:1.18 Sun Apr 12 07:49:58 2020
+++ src/sys/arch/aarch64/conf/Makefile.aarch64 Mon Apr 13 05:40:25 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.aarch64,v 1.18 2020/04/12 07:49:58 maxv Exp $
+# $NetBSD: Makefile.aarch64,v 1.19 2020/04/13 05:40:25 maxv Exp $
# Makefile for NetBSD
#
@@ -39,9 +39,18 @@ CFLAGS+= -fno-omit-frame-pointer
CFLAGS+= -mno-omit-leaf-frame-pointer
#CFLAGS+= -mno-unaligned-access
-.if ${ARMV83_PAC:U0} > 0 && ${HAVE_LLVM:Uno} == "yes"
+.if ${HAVE_LLVM:Uno} == "yes"
+.if ${ARMV83_PAC:U0} > 0 && ${ARMV85_BTI:U0} > 0
+CFLAGS+= -mbranch-protection=pac-ret+bti
+.else
+.if ${ARMV83_PAC:U0} > 0
CFLAGS+= -mbranch-protection=pac-ret
.endif
+.if ${ARMV85_BTI:U0} > 0
+CFLAGS+= -mbranch-protection=bti
+.endif
+.endif
+.endif
.if ${KASAN:U0} > 0 && ${HAVE_GCC:U0} > 0
KASANFLAGS= -fsanitize=kernel-address \
Index: src/sys/arch/arm/conf/files.arm
diff -u src/sys/arch/arm/conf/files.arm:1.154 src/sys/arch/arm/conf/files.arm:1.155
--- src/sys/arch/arm/conf/files.arm:1.154 Sun Apr 12 07:49:58 2020
+++ src/sys/arch/arm/conf/files.arm Mon Apr 13 05:40:25 2020
@@ -1,4 +1,4 @@
-# $NetBSD: files.arm,v 1.154 2020/04/12 07:49:58 maxv Exp $
+# $NetBSD: files.arm,v 1.155 2020/04/13 05:40:25 maxv Exp $
# temporary define to allow easy moving to ../arch/arm/arm32
defflag ARM32
@@ -80,6 +80,7 @@ defparam opt_arm_debug.h EARLYCONS
# ARMv8-specific options
defflag opt_cpuoptions.h ARMV83_PAC
+defflag opt_cpuoptions.h ARMV85_BTI
# Board-specific bus_space(9)/bus_dma(9) definitions
defflag opt_arm_bus_space.h __BUS_SPACE_HAS_STREAM_METHODS
Index: src/sys/arch/arm/include/asm.h
diff -u src/sys/arch/arm/include/asm.h:1.30 src/sys/arch/arm/include/asm.h:1.31
--- src/sys/arch/arm/include/asm.h:1.30 Sun Jan 27 04:52:07 2019
+++ src/sys/arch/arm/include/asm.h Mon Apr 13 05:40:25 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: asm.h,v 1.30 2019/01/27 04:52:07 dholland Exp $ */
+/* $NetBSD: asm.h,v 1.31 2020/04/13 05:40:25 maxv Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -67,6 +67,9 @@
#define _ARM_ASM_H_
#include <arm/cdefs.h>
+#if defined(_KERNEL_OPT)
+#include "opt_cpuoptions.h"
+#endif
#ifdef __thumb__
#define THUMB_INSN(n) n
@@ -156,8 +159,16 @@
#endif
#endif
-#define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
-#define ENTRY_NP(y) _ENTRY(_C_LABEL(y))
+#ifdef ARMV85_BTI
+#define _BTI_PROLOGUE \
+ .byte 0x5F, 0x24, 0x03, 0xD5 /* the "bti c" instruction */
+#else
+#define _BTI_PROLOGUE /* nothing */
+#endif
+
+#define ENTRY(y) _ENTRY(_C_LABEL(y)); _BTI_PROLOGUE ; _PROF_PROLOGUE
+#define ENTRY_NP(y) _ENTRY(_C_LABEL(y)); _BTI_PROLOGUE
+#define ENTRY_NBTI(y) _ENTRY(_C_LABEL(y))
#define END(y) _END(_C_LABEL(y))
#define ARM_ENTRY(y) _ARM_ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
#define ARM_ENTRY_NP(y) _ARM_ENTRY(_C_LABEL(y))
Index: src/sys/arch/evbarm/conf/GENERIC64
diff -u src/sys/arch/evbarm/conf/GENERIC64:1.150 src/sys/arch/evbarm/conf/GENERIC64:1.151
--- src/sys/arch/evbarm/conf/GENERIC64:1.150 Sun Apr 12 07:49:58 2020
+++ src/sys/arch/evbarm/conf/GENERIC64 Mon Apr 13 05:40:26 2020
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC64,v 1.150 2020/04/12 07:49:58 maxv Exp $
+# $NetBSD: GENERIC64,v 1.151 2020/04/13 05:40:26 maxv Exp $
#
# GENERIC ARM (aarch64) kernel
#
@@ -168,6 +168,10 @@ options INCLUDE_CONFIG_FILE
#makeoptions ARMV83_PAC=1
#options ARMV83_PAC
+# Branch Target Identification (BTI).
+#makeoptions ARMV85_BTI=1
+#options ARMV85_BTI
+
# Kernel Address Sanitizer (kASan). The quarantine is optional and can
# help KASAN find more use-after-frees. Use KASAN_PANIC if you want panics
# instead of warnings.