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;
}