Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Add support for Branch Target Identification (BTI).
details: https://anonhg.NetBSD.org/src/rev/ffb5a58c56ef
branches: trunk
changeset: 1009104:ffb5a58c56ef
user: maxv <maxv%NetBSD.org@localhost>
date: Mon Apr 13 05:40:25 2020 +0000
description:
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.
diffstat:
sys/arch/aarch64/aarch64/aarch64_machdep.c | 33 ++++++++++++++++++++++++++++-
sys/arch/aarch64/aarch64/cpuswitch.S | 7 +++--
sys/arch/aarch64/aarch64/pmap.c | 6 +++-
sys/arch/aarch64/aarch64/pmapboot.c | 7 ++++-
sys/arch/aarch64/aarch64/trap.c | 5 ++-
sys/arch/aarch64/aarch64/vectors.S | 6 ++--
sys/arch/aarch64/conf/Makefile.aarch64 | 13 ++++++++++-
sys/arch/arm/conf/files.arm | 3 +-
sys/arch/arm/include/asm.h | 17 ++++++++++++--
sys/arch/evbarm/conf/GENERIC64 | 6 ++++-
10 files changed, 82 insertions(+), 21 deletions(-)
diffs (truncated from 316 to 300 lines):
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/aarch64/aarch64/aarch64_machdep.c
--- a/sys/arch/aarch64/aarch64/aarch64_machdep.c Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/aarch64/aarch64/aarch64_machdep.c Mon Apr 13 05:40:25 2020 +0000
@@ -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 @@
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 @@
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 @@
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
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/aarch64/aarch64/cpuswitch.S
--- a/sys/arch/aarch64/aarch64/cpuswitch.S Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/aarch64/aarch64/cpuswitch.S Mon Apr 13 05:40:25 2020 +0000
@@ -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 @@
*/
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
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/aarch64/aarch64/pmap.c
--- a/sys/arch/aarch64/aarch64/pmap.c Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/aarch64/aarch64/pmap.c Mon Apr 13 05:40:25 2020 +0000
@@ -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 <ryo%nerv.org@localhost>
@@ -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 @@
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)
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/aarch64/aarch64/pmapboot.c
--- a/sys/arch/aarch64/aarch64/pmapboot.c Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/aarch64/aarch64/pmapboot.c Mon Apr 13 05:40:25 2020 +0000
@@ -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 <ryo%nerv.org@localhost>
@@ -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 @@
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;
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/aarch64/aarch64/trap.c
--- a/sys/arch/aarch64/aarch64/trap.c Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/aarch64/aarch64/trap.c Mon Apr 13 05:40:25 2020 +0000
@@ -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 @@
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,
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/aarch64/aarch64/vectors.S
--- a/sys/arch/aarch64/aarch64/vectors.S Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/aarch64/aarch64/vectors.S Mon Apr 13 05:40:25 2020 +0000
@@ -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 @@
* 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)
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/aarch64/conf/Makefile.aarch64
--- a/sys/arch/aarch64/conf/Makefile.aarch64 Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/aarch64/conf/Makefile.aarch64 Mon Apr 13 05:40:25 2020 +0000
@@ -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+= -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 \
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/arm/conf/files.arm
--- a/sys/arch/arm/conf/files.arm Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/arm/conf/files.arm Mon Apr 13 05:40:25 2020 +0000
@@ -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 @@
# 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
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/arm/include/asm.h
--- a/sys/arch/arm/include/asm.h Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/arm/include/asm.h Mon Apr 13 05:40:25 2020 +0000
@@ -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))
diff -r db4fb99bfbd0 -r ffb5a58c56ef sys/arch/evbarm/conf/GENERIC64
--- a/sys/arch/evbarm/conf/GENERIC64 Mon Apr 13 00:27:16 2020 +0000
+++ b/sys/arch/evbarm/conf/GENERIC64 Mon Apr 13 05:40:25 2020 +0000
@@ -1,5 +1,5 @@
#
Home |
Main Index |
Thread Index |
Old Index