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