Module Name:    src
Committed By:   maxv
Date:           Sun Aug 12 08:17:50 UTC 2018

Modified Files:
        src/sys/arch/amd64/amd64: machdep.c
        src/sys/arch/amd64/include: pmap.h vmparam.h
        src/sys/arch/x86/x86: pmap.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.309 -r1.310 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.48 -r1.49 src/sys/arch/amd64/include/pmap.h
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/amd64/include/vmparam.h
cvs rdiff -u -r1.295 -r1.296 src/sys/arch/x86/x86/pmap.c

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/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.309 src/sys/arch/amd64/amd64/machdep.c:1.310
--- src/sys/arch/amd64/amd64/machdep.c:1.309	Thu Jul 26 09:29:08 2018
+++ src/sys/arch/amd64/amd64/machdep.c	Sun Aug 12 08:17:50 2018
@@ -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 vm_map *module_map;
 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 @@ init_slotspace(void)
 	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 @@ init_slotspace(void)
 	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

Index: src/sys/arch/amd64/include/pmap.h
diff -u src/sys/arch/amd64/include/pmap.h:1.48 src/sys/arch/amd64/include/pmap.h:1.49
--- src/sys/arch/amd64/include/pmap.h:1.48	Fri Jul 27 07:35:09 2018
+++ src/sys/arch/amd64/include/pmap.h	Sun Aug 12 08:17:50 2018
@@ -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) */

Index: src/sys/arch/amd64/include/vmparam.h
diff -u src/sys/arch/amd64/include/vmparam.h:1.45 src/sys/arch/amd64/include/vmparam.h:1.46
--- src/sys/arch/amd64/include/vmparam.h:1.45	Mon Nov 13 07:06:49 2017
+++ src/sys/arch/amd64/include/vmparam.h	Sun Aug 12 08:17:50 2018
@@ -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
 
 /*

Index: src/sys/arch/x86/x86/pmap.c
diff -u src/sys/arch/x86/x86/pmap.c:1.295 src/sys/arch/x86/x86/pmap.c:1.296
--- src/sys/arch/x86/x86/pmap.c:1.295	Thu Jul 26 17:20:08 2018
+++ src/sys/arch/x86/x86/pmap.c	Sun Aug 12 08:17:50 2018
@@ -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 @@ slotspace_copy(int type, pd_entry_t *dst
 #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 @@ slotspace_rand(int type, size_t sz, size
 
 	/* 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 @@ slotspace_rand(int type, size_t sz, size
 	if (slotspace.area[type].dropmax) {
 		slotspace.area[type].mslot = slotspace.area[type].nslot;
 	}
+	slotspace.area[type].active = true;
 
 	return va;
 }

Reply via email to