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 kernel main memory. VM_MIN...



details:   https://anonhg.NetBSD.org/src/rev/b5e9ed306313
branches:  trunk
changeset: 992012:b5e9ed306313
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sun Aug 12 08:17:50 2018 +0000

description:
More ASLR: randomize the kernel main memory. VM_MIN_KERNEL_ADDRESS becomes
variable, and its location is chosen at boot time. There is room for
improvement, since for now we ask for an alignment of NBPD_L4.

This is enabled by default in GENERIC, but not in Xen. Tested extensively
on GENERIC and GENERIC_KASLR, XEN3_DOM0 still boots fine.

diffstat:

 sys/arch/amd64/amd64/machdep.c   |  23 +++++++++++++++++++-
 sys/arch/amd64/include/pmap.h    |   4 +-
 sys/arch/amd64/include/vmparam.h |  16 ++++++++++----
 sys/arch/x86/x86/pmap.c          |  44 ++++++++++++++++++++++++++++++----------
 4 files changed, 67 insertions(+), 20 deletions(-)

diffs (200 lines):

diff -r fe6eb9c9cd80 -r b5e9ed306313 sys/arch/amd64/amd64/machdep.c
--- a/sys/arch/amd64/amd64/machdep.c    Sun Aug 12 08:00:32 2018 +0000
+++ b/sys/arch/amd64/amd64/machdep.c    Sun Aug 12 08:17:50 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.309 2018/07/26 09:29:08 maxv Exp $       */
+/*     $NetBSD: machdep.c,v 1.310 2018/08/12 08:17:50 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.309 2018/07/26 09:29:08 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.310 2018/08/12 08:17:50 maxv Exp $");
 
 #include "opt_modular.h"
 #include "opt_user_ldt.h"
@@ -264,6 +264,9 @@
 extern struct bootspace bootspace;
 extern struct slotspace slotspace;
 
+vaddr_t vm_min_kernel_address __read_mostly = VM_MIN_KERNEL_ADDRESS_DEFAULT;
+vaddr_t vm_max_kernel_address __read_mostly = VM_MAX_KERNEL_ADDRESS_DEFAULT;
+
 struct vm_map *phys_map = NULL;
 
 extern paddr_t lowmem_rsvd;
@@ -1605,12 +1608,14 @@
        slotspace.area[SLAREA_PTE].active = true;
        slotspace.area[SLAREA_PTE].dropmax = false;
 
+#ifdef XEN
        /* 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;
+#endif
 
 #ifdef __HAVE_PCPU_AREA
        /* Per-CPU. */
@@ -1636,6 +1641,20 @@
        slotspace.area[SLAREA_KERN].nslot = 1;
        slotspace.area[SLAREA_KERN].active = true;
        slotspace.area[SLAREA_KERN].dropmax = false;
+
+#ifndef XEN
+       vaddr_t slotspace_rand(int, size_t, size_t);
+       vaddr_t va;
+
+       /* Main. */
+       slotspace.area[SLAREA_MAIN].mslot = NKL4_MAX_ENTRIES+1;
+       slotspace.area[SLAREA_MAIN].dropmax = false;
+       va = slotspace_rand(SLAREA_MAIN, NKL4_MAX_ENTRIES * NBPD_L4,
+           NBPD_L4);
+
+       vm_min_kernel_address = va;
+       vm_max_kernel_address = va + NKL4_MAX_ENTRIES * NBPD_L4;
+#endif
 }
 
 void
diff -r fe6eb9c9cd80 -r b5e9ed306313 sys/arch/amd64/include/pmap.h
--- a/sys/arch/amd64/include/pmap.h     Sun Aug 12 08:00:32 2018 +0000
+++ b/sys/arch/amd64/include/pmap.h     Sun Aug 12 08:17:50 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.48 2018/07/27 07:35:09 maxv Exp $   */
+/*     $NetBSD: pmap.h,v 1.49 2018/08/12 08:17:50 maxv Exp $   */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -139,7 +139,7 @@
 
 #define L4_SLOT_PTE            255
 #ifndef XEN
-#define L4_SLOT_KERN           256 /* pl4_i(VM_MIN_KERNEL_ADDRESS) */
+#define L4_SLOT_KERN           slotspace.area[SLAREA_MAIN].sslot
 #else
 /* Xen use slots 256-272, let's move farther */
 #define L4_SLOT_KERN           320 /* pl4_i(VM_MIN_KERNEL_ADDRESS) */
diff -r fe6eb9c9cd80 -r b5e9ed306313 sys/arch/amd64/include/vmparam.h
--- a/sys/arch/amd64/include/vmparam.h  Sun Aug 12 08:00:32 2018 +0000
+++ b/sys/arch/amd64/include/vmparam.h  Sun Aug 12 08:17:50 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vmparam.h,v 1.45 2017/11/13 07:06:49 wiz Exp $ */
+/*     $NetBSD: vmparam.h,v 1.46 2018/08/12 08:17:50 maxv Exp $        */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -126,11 +126,17 @@
  * MAX = MIN + NKL4_MAX_ENTRIES * NBPD_L4
  */
 #ifndef XEN
-#define VM_MIN_KERNEL_ADDRESS  0xffff800000000000
-#define VM_MAX_KERNEL_ADDRESS  0xffffa00000000000
+#define VM_MIN_KERNEL_ADDRESS_DEFAULT  0xffff800000000000
+#define VM_MAX_KERNEL_ADDRESS_DEFAULT  0xffffa00000000000
+extern vaddr_t vm_min_kernel_address;
+extern vaddr_t vm_max_kernel_address;
+#define VM_MIN_KERNEL_ADDRESS  vm_min_kernel_address
+#define VM_MAX_KERNEL_ADDRESS  vm_max_kernel_address
 #else
-#define VM_MIN_KERNEL_ADDRESS  0xffffa00000000000
-#define VM_MAX_KERNEL_ADDRESS  0xffffc00000000000
+#define VM_MIN_KERNEL_ADDRESS_DEFAULT  0xffffa00000000000
+#define VM_MAX_KERNEL_ADDRESS_DEFAULT  0xffffc00000000000
+#define VM_MIN_KERNEL_ADDRESS  VM_MIN_KERNEL_ADDRESS_DEFAULT
+#define VM_MAX_KERNEL_ADDRESS  VM_MAX_KERNEL_ADDRESS_DEFAULT
 #endif
 
 /*
diff -r fe6eb9c9cd80 -r b5e9ed306313 sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c   Sun Aug 12 08:00:32 2018 +0000
+++ b/sys/arch/x86/x86/pmap.c   Sun Aug 12 08:17:50 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.295 2018/07/26 17:20:08 maxv Exp $  */
+/*     $NetBSD: pmap.c,v 1.296 2018/08/12 08:17:50 maxv Exp $  */
 
 /*
  * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc.
@@ -157,7 +157,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.295 2018/07/26 17:20:08 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.296 2018/08/12 08:17:50 maxv Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -1394,12 +1394,14 @@
 #endif
 
 #if defined(__HAVE_DIRECT_MAP)
+vaddr_t slotspace_rand(int, size_t, size_t);
+
 /*
  * Randomize the location of an area. We count the holes in the VM space. We
  * randomly select one hole, and then randomly select an area within that hole.
  * Finally we update the associated entry in the slotspace structure.
  */
-static vaddr_t
+vaddr_t
 slotspace_rand(int type, size_t sz, size_t align)
 {
        struct {
@@ -1415,17 +1417,36 @@
 
        /* Get the holes. */
        nholes = 0;
-       for (i = 0; i < SLSPACE_NAREAS-1; i++) {
-               startsl = slotspace.area[i].sslot;
-               if (slotspace.area[i].active)
-                       startsl += slotspace.area[i].mslot;
-               endsl = slotspace.area[i+1].sslot;
-               if (endsl - startsl >= nslots) {
-                       holes[nholes].start = startsl;
-                       holes[nholes].end = endsl;
+       size_t curslot = 0 + 255; /* end of SLAREA_USER */
+       while (1) {
+               /*
+                * Find the first occupied slot after the current one.
+                * The area between the two is a hole.
+                */
+               size_t minsslot = 512;
+               size_t minnslot = 0;
+               for (i = 0; i < SLSPACE_NAREAS-1; i++) {
+                       if (!slotspace.area[i].active)
+                               continue;
+                       if (slotspace.area[i].sslot >= curslot &&
+                           slotspace.area[i].sslot < minsslot) {
+                               minsslot = slotspace.area[i].sslot;
+                               minnslot = slotspace.area[i].nslot;
+                       }
+               }
+               if (minsslot == 512) {
+                       break;
+               }
+
+               if (minsslot - curslot >= nslots) {
+                       holes[nholes].start = curslot;
+                       holes[nholes].end = minsslot;
                        nholes++;
                }
+
+               curslot = minsslot + minnslot;
        }
+
        if (nholes == 0) {
                panic("%s: impossible", __func__);
        }
@@ -1451,6 +1472,7 @@
        if (slotspace.area[type].dropmax) {
                slotspace.area[type].mslot = slotspace.area[type].nslot;
        }
+       slotspace.area[type].active = true;
 
        return va;
 }



Home | Main Index | Thread Index | Old Index