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/357946c6ba84
branches:  trunk
changeset: 971069:357946c6ba84
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 9622a46832d3 -r 357946c6ba84 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 9622a46832d3 -r 357946c6ba84 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 9622a46832d3 -r 357946c6ba84 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 9622a46832d3 -r 357946c6ba84 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 9622a46832d3 -r 357946c6ba84 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 9622a46832d3 -r 357946c6ba84 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 9622a46832d3 -r 357946c6ba84 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 9622a46832d3 -r 357946c6ba84 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 9622a46832d3 -r 357946c6ba84 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 9622a46832d3 -r 357946c6ba84 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