Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch More ASLR. Randomize the location of the direct map...



details:   https://anonhg.NetBSD.org/src/rev/8f4dc867d209
branches:  trunk
changeset: 320807:8f4dc867d209
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sat Jul 21 06:09:13 2018 +0000

description:
More ASLR. Randomize the location of the direct map at boot time on amd64.
This doesn't need "options KASLR" and works on GENERIC. Will soon be
enabled by default.

The location of the areas is abstracted in a slotspace structure. Ideally
we should always use this structure when touching the L4 slots, instead of
the current cocktail of global variables and constants.

machdep initializes the structure with the default values, and we then
randomize its dmap entry. Ideally machdep should randomize everything at
once, but in the case of the direct map its size is determined a little
later in the boot procedure, so we're forced to randomize its location
later too.

diffstat:

 sys/arch/amd64/amd64/cpufunc.S |  10 +++-
 sys/arch/amd64/amd64/locore.S  |   3 +-
 sys/arch/amd64/amd64/machdep.c |  58 ++++++++++++++++++++++++-
 sys/arch/x86/include/cpu_rng.h |   3 +-
 sys/arch/x86/include/pmap.h    |  21 ++++++++-
 sys/arch/x86/x86/cpu_rng.c     |  52 ++++++++++++++++++++++-
 sys/arch/x86/x86/pmap.c        |  95 ++++++++++++++++++++++++++++++++++++++---
 7 files changed, 226 insertions(+), 16 deletions(-)

diffs (truncated from 420 to 300 lines):

diff -r ae6c7da7cf1f -r 8f4dc867d209 sys/arch/amd64/amd64/cpufunc.S
--- a/sys/arch/amd64/amd64/cpufunc.S    Fri Jul 20 22:47:26 2018 +0000
+++ b/sys/arch/amd64/amd64/cpufunc.S    Sat Jul 21 06:09:13 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpufunc.S,v 1.32 2018/07/14 14:29:40 maxv Exp $        */
+/*     $NetBSD: cpufunc.S,v 1.33 2018/07/21 06:09:13 maxv Exp $        */
 
 /*
  * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc.
@@ -383,6 +383,14 @@
        ret
 END(rdpmc)
 
+ENTRY(rdtsc)
+       xorq    %rax,%rax
+       rdtsc
+       shlq    $32,%rdx
+       orq     %rdx,%rax
+       ret
+END(rdtsc)
+
 ENTRY(breakpoint)
        pushq   %rbp
        movq    %rsp, %rbp
diff -r ae6c7da7cf1f -r 8f4dc867d209 sys/arch/amd64/amd64/locore.S
--- a/sys/arch/amd64/amd64/locore.S     Fri Jul 20 22:47:26 2018 +0000
+++ b/sys/arch/amd64/amd64/locore.S     Sat Jul 21 06:09:13 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.S,v 1.171 2018/07/14 14:29:40 maxv Exp $        */
+/*     $NetBSD: locore.S,v 1.172 2018/07/21 06:09:13 maxv Exp $        */
 
 /*
  * Copyright-o-rama!
@@ -975,6 +975,7 @@
 
        pushq   %rdi
        call    _C_LABEL(init_bootspace)
+       call    _C_LABEL(init_slotspace)
        popq    %rdi
        call    _C_LABEL(init_x86_64)
        call    _C_LABEL(main)
diff -r ae6c7da7cf1f -r 8f4dc867d209 sys/arch/amd64/amd64/machdep.c
--- a/sys/arch/amd64/amd64/machdep.c    Fri Jul 20 22:47:26 2018 +0000
+++ b/sys/arch/amd64/amd64/machdep.c    Sat Jul 21 06:09:13 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.306 2018/07/12 19:48:16 maxv Exp $       */
+/*     $NetBSD: machdep.c,v 1.307 2018/07/21 06:09:13 maxv Exp $       */
 
 /*
  * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -110,7 +110,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.306 2018/07/12 19:48:16 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.307 2018/07/21 06:09:13 maxv Exp $");
 
 #include "opt_modular.h"
 #include "opt_user_ldt.h"
@@ -262,6 +262,7 @@
 static struct vm_map module_map_store;
 extern struct vm_map *module_map;
 extern struct bootspace bootspace;
+extern struct slotspace slotspace;
 
 struct vm_map *phys_map = NULL;
 
@@ -322,6 +323,7 @@
 int dumpsys_seg(paddr_t, paddr_t);
 
 void init_bootspace(void);
+void init_slotspace(void);
 void init_x86_64(paddr_t);
 
 /*
@@ -1590,6 +1592,58 @@
 }
 
 void
+init_slotspace(void)
+{
+       memset(&slotspace, 0, sizeof(slotspace));
+
+       /* User. */
+       slotspace.area[SLAREA_USER].sslot = 0;
+       slotspace.area[SLAREA_USER].mslot = PDIR_SLOT_PTE;
+       slotspace.area[SLAREA_USER].nslot = PDIR_SLOT_PTE;
+       slotspace.area[SLAREA_USER].active = true;
+       slotspace.area[SLAREA_USER].dropmax = false;
+
+       /* PTE. */
+       slotspace.area[SLAREA_PTE].sslot = PDIR_SLOT_PTE;
+       slotspace.area[SLAREA_PTE].mslot = 1;
+       slotspace.area[SLAREA_PTE].nslot = 1;
+       slotspace.area[SLAREA_PTE].active = true;
+       slotspace.area[SLAREA_PTE].dropmax = false;
+
+       /* Main. */
+       slotspace.area[SLAREA_MAIN].sslot = PDIR_SLOT_KERN;
+       slotspace.area[SLAREA_MAIN].mslot = NKL4_MAX_ENTRIES;
+       slotspace.area[SLAREA_MAIN].nslot = 0 /* variable */;
+       slotspace.area[SLAREA_MAIN].active = true;
+       slotspace.area[SLAREA_MAIN].dropmax = false;
+
+#ifdef __HAVE_PCPU_AREA
+       /* Per-CPU. */
+       slotspace.area[SLAREA_PCPU].sslot = PDIR_SLOT_PCPU;
+       slotspace.area[SLAREA_PCPU].mslot = 1;
+       slotspace.area[SLAREA_PCPU].nslot = 1;
+       slotspace.area[SLAREA_PCPU].active = true;
+       slotspace.area[SLAREA_PCPU].dropmax = false;
+#endif
+
+#ifdef __HAVE_DIRECT_MAP
+       /* Direct Map. */
+       slotspace.area[SLAREA_DMAP].sslot = PDIR_SLOT_DIRECT;
+       slotspace.area[SLAREA_DMAP].mslot = NL4_SLOT_DIRECT+1;
+       slotspace.area[SLAREA_DMAP].nslot = 0 /* variable */;
+       slotspace.area[SLAREA_DMAP].active = false;
+       slotspace.area[SLAREA_DMAP].dropmax = true;
+#endif
+
+       /* Kernel. */
+       slotspace.area[SLAREA_KERN].sslot = L4_SLOT_KERNBASE;
+       slotspace.area[SLAREA_KERN].mslot = 1;
+       slotspace.area[SLAREA_KERN].nslot = 1;
+       slotspace.area[SLAREA_KERN].active = true;
+       slotspace.area[SLAREA_KERN].dropmax = false;
+}
+
+void
 init_x86_64(paddr_t first_avail)
 {
        extern void consinit(void);
diff -r ae6c7da7cf1f -r 8f4dc867d209 sys/arch/x86/include/cpu_rng.h
--- a/sys/arch/x86/include/cpu_rng.h    Fri Jul 20 22:47:26 2018 +0000
+++ b/sys/arch/x86/include/cpu_rng.h    Sat Jul 21 06:09:13 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_rng.h,v 1.1 2016/02/27 00:09:45 tls Exp $ */
+/* $NetBSD: cpu_rng.h,v 1.2 2018/07/21 06:09:13 maxv Exp $ */
 
 #ifndef _X86_CPU_RNG_H_
 #define _X86_CPU_RNG_H_
@@ -38,5 +38,6 @@
 
 bool cpu_rng_init(void);
 size_t cpu_rng(cpu_rng_t *);
+void cpu_earlyrng(void *, size_t);
 
 #endif /* _X86_CPU_RNG_H_ */
diff -r ae6c7da7cf1f -r 8f4dc867d209 sys/arch/x86/include/pmap.h
--- a/sys/arch/x86/include/pmap.h       Fri Jul 20 22:47:26 2018 +0000
+++ b/sys/arch/x86/include/pmap.h       Sat Jul 21 06:09:13 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.80 2018/06/20 11:49:38 maxv Exp $   */
+/*     $NetBSD: pmap.h,v 1.81 2018/07/21 06:09:13 maxv Exp $   */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -154,6 +154,25 @@
        vaddr_t emodule;
 };
 
+#define SLSPACE_NONE   0
+#define SLAREA_USER    1
+#define SLAREA_PTE     2
+#define SLAREA_MAIN    3
+#define SLAREA_PCPU    4
+#define SLAREA_DMAP    5
+#define SLAREA_KERN    6
+#define SLSPACE_NAREAS 7
+
+struct slotspace {
+       struct {
+               size_t sslot; /* start slot */
+               size_t nslot; /* # of slots */
+               size_t mslot; /* max # of slots */
+               bool active;  /* area is active */
+               bool dropmax; /* !resizable */
+       } area[SLSPACE_NAREAS];
+};
+
 #ifndef MAXGDTSIZ
 #define MAXGDTSIZ 65536 /* XXX */
 #endif
diff -r ae6c7da7cf1f -r 8f4dc867d209 sys/arch/x86/x86/cpu_rng.c
--- a/sys/arch/x86/x86/cpu_rng.c        Fri Jul 20 22:47:26 2018 +0000
+++ b/sys/arch/x86/x86/cpu_rng.c        Sat Jul 21 06:09:13 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_rng.c,v 1.5 2016/02/29 00:17:54 riastradh Exp $ */
+/* $NetBSD: cpu_rng.c,v 1.6 2018/07/21 06:09:13 maxv Exp $ */
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -38,6 +38,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/cpu.h>
+#include <sys/sha2.h>
 
 #include <x86/specialreg.h>
 
@@ -193,3 +194,52 @@
                panic("cpu_rng: unknown mode %d", (int)cpu_rng_mode);
        }
 }
+
+/* -------------------------------------------------------------------------- */
+
+static uint64_t earlyrng_state;
+
+/*
+ * Small PRNG, that can be used very early. The only requirement is that
+ * cpu_probe got called before.
+ */
+void
+cpu_earlyrng(void *out, size_t sz)
+{
+       uint8_t digest[SHA512_DIGEST_LENGTH];
+       SHA512_CTX ctx;
+       cpu_rng_t buf[8];
+       uint64_t val;
+       int i;
+
+       bool has_rdseed = (cpu_feature[5] & CPUID_SEF_RDSEED) != 0;
+       bool has_rdrand = (cpu_feature[1] & CPUID2_RDRAND) != 0;
+
+       KASSERT(sz + sizeof(uint64_t) <= SHA512_DIGEST_LENGTH);
+
+       SHA512_Init(&ctx);
+
+       SHA512_Update(&ctx, (uint8_t *)&earlyrng_state, sizeof(earlyrng_state));
+       if (has_rdseed) {
+               for (i = 0; i < 8; i++) {
+                       if (cpu_rng_rdseed(&buf[i]) == 0) {
+                               break;
+                       }
+               }
+               SHA512_Update(&ctx, (uint8_t *)buf, i * sizeof(cpu_rng_t));
+       } else if (has_rdrand) {
+               for (i = 0; i < 8; i++) {
+                       if (cpu_rng_rdrand(&buf[i]) == 0) {
+                               break;
+                       }
+               }
+               SHA512_Update(&ctx, (uint8_t *)buf, i * sizeof(cpu_rng_t));
+       }
+       val = rdtsc();
+       SHA512_Update(&ctx, (uint8_t *)&val, sizeof(val));
+
+       SHA512_Final(digest, &ctx);
+
+       memcpy(out, digest, sz);
+       memcpy(&earlyrng_state, &digest[sz], sizeof(earlyrng_state));
+}
diff -r ae6c7da7cf1f -r 8f4dc867d209 sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c   Fri Jul 20 22:47:26 2018 +0000
+++ b/sys/arch/x86/x86/pmap.c   Sat Jul 21 06:09:13 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.291 2018/06/20 11:57:22 maxv Exp $  */
+/*     $NetBSD: pmap.c,v 1.292 2018/07/21 06:09:13 maxv Exp $  */
 
 /*
  * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc.
@@ -170,7 +170,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.291 2018/06/20 11:57:22 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.292 2018/07/21 06:09:13 maxv Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -199,6 +199,7 @@
 #include <machine/isa_machdep.h>
 #include <machine/cpuvar.h>
 #include <machine/cputypes.h>
+#include <machine/cpu_rng.h>
 
 #include <x86/pmap.h>
 #include <x86/pmap_pv.h>
@@ -372,6 +373,7 @@
 struct pmap *const kernel_pmap_ptr = &kernel_pmap_store;
 
 struct bootspace bootspace __read_mostly;
+struct slotspace slotspace __read_mostly;
 
 /*
  * pmap_pg_nx: if our processor supports PG_NX in the PTE then we
@@ -501,8 +503,6 @@
 #ifdef __HAVE_DIRECT_MAP
 vaddr_t pmap_direct_base __read_mostly;
 vaddr_t pmap_direct_end __read_mostly;
-size_t pmap_direct_pdpe __read_mostly;
-size_t pmap_direct_npdp __read_mostly;
 #endif
 
 #ifndef __HAVE_DIRECT_MAP
@@ -1394,6 +1394,80 @@
 }



Home | Main Index | Thread Index | Old Index