Module Name: src Committed By: maxv Date: Sun Aug 12 15:31:01 UTC 2018
Modified Files: src/sys/arch/amd64/amd64: genassym.cf locore.S machdep.c prekern.c src/sys/arch/amd64/include: pmap.h src/sys/arch/x86/x86: pmap.c Log Message: More ASLR: randomize the location of the PTE area. The PTE slot is not created in locore anymore, but a little later; by using the already entered L4 page, rather than the recursive slot itself (which doesn't exist yet). In the prekern we still map the slot - the prekern behaves as an external locore -, because we need it as part of the randomization/relocation work. The kernel then removes this slot, and regenerates a randomized one. Tested on GENERIC and GENERIC_KASLR, Xen doesn't have it and dom0 still boots fine. To generate a diff of this commit: cvs rdiff -u -r1.69 -r1.70 src/sys/arch/amd64/amd64/genassym.cf cvs rdiff -u -r1.173 -r1.174 src/sys/arch/amd64/amd64/locore.S cvs rdiff -u -r1.313 -r1.314 src/sys/arch/amd64/amd64/machdep.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/amd64/amd64/prekern.c cvs rdiff -u -r1.52 -r1.53 src/sys/arch/amd64/include/pmap.h cvs rdiff -u -r1.301 -r1.302 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/genassym.cf diff -u src/sys/arch/amd64/amd64/genassym.cf:1.69 src/sys/arch/amd64/amd64/genassym.cf:1.70 --- src/sys/arch/amd64/amd64/genassym.cf:1.69 Sun Aug 12 06:11:47 2018 +++ src/sys/arch/amd64/amd64/genassym.cf Sun Aug 12 15:31:01 2018 @@ -1,4 +1,4 @@ -# $NetBSD: genassym.cf,v 1.69 2018/08/12 06:11:47 maxv Exp $ +# $NetBSD: genassym.cf,v 1.70 2018/08/12 15:31:01 maxv Exp $ # # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -143,8 +143,6 @@ define L3_SLOT_KERNBASE pl3_pi(KERNBASE) define L2_SLOT_KERNBASE pl2_pi(KERNBASE) define L1_SLOT_KERNBASE pl1_pi(KERNBASE) -define PDIR_SLOT_PTE PDIR_SLOT_PTE - define PDE_SIZE sizeof(pd_entry_t) define VM_MAXUSER_ADDRESS (unsigned long long)VM_MAXUSER_ADDRESS Index: src/sys/arch/amd64/amd64/locore.S diff -u src/sys/arch/amd64/amd64/locore.S:1.173 src/sys/arch/amd64/amd64/locore.S:1.174 --- src/sys/arch/amd64/amd64/locore.S:1.173 Thu Jul 26 09:29:08 2018 +++ src/sys/arch/amd64/amd64/locore.S Sun Aug 12 15:31:01 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.173 2018/07/26 09:29:08 maxv Exp $ */ +/* $NetBSD: locore.S,v 1.174 2018/08/12 15:31:01 maxv Exp $ */ /* * Copyright-o-rama! @@ -770,13 +770,6 @@ ENTRY(start) movl $NKL4_KIMG_ENTRIES,%ecx fillkpt - /* Install recursive top level PDE (one entry) */ - leal (PROC0_PML4_OFF + PDIR_SLOT_PTE * PDE_SIZE)(%esi),%ebx - leal (PROC0_PML4_OFF)(%esi),%eax - orl $(PG_V|PG_KW),%eax - movl $1,%ecx - fillkpt_nox - /* * Startup checklist: * 1. Enable PAE (and SSE while here). Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.313 src/sys/arch/amd64/amd64/machdep.c:1.314 --- src/sys/arch/amd64/amd64/machdep.c:1.313 Sun Aug 12 12:42:53 2018 +++ src/sys/arch/amd64/amd64/machdep.c Sun Aug 12 15:31:01 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.313 2018/08/12 12:42:53 maxv Exp $ */ +/* $NetBSD: machdep.c,v 1.314 2018/08/12 15:31:01 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.313 2018/08/12 12:42:53 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.314 2018/08/12 15:31:01 maxv Exp $"); #include "opt_modular.h" #include "opt_user_ldt.h" @@ -266,6 +266,7 @@ 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; +pd_entry_t *pte_base __read_mostly; struct vm_map *phys_map = NULL; @@ -1589,6 +1590,21 @@ init_bootspace(void) bootspace.emodule = KERNBASE + NKL2_KIMG_ENTRIES * NBPD_L2; } +static void init_pte(void) +{ +#ifndef XEN + extern uint32_t nox_flag; + pd_entry_t *pdir = (pd_entry_t *)bootspace.pdir; + pdir[L4_SLOT_PTE] = PDPpaddr | PG_KW | ((uint64_t)nox_flag << 32) | + PG_V; +#endif + + extern pd_entry_t *normal_pdes[3]; + normal_pdes[0] = L2_BASE; + normal_pdes[1] = L3_BASE; + normal_pdes[2] = L4_BASE; +} + void init_slotspace(void) { @@ -1604,12 +1620,14 @@ init_slotspace(void) slotspace.area[SLAREA_USER].active = true; slotspace.area[SLAREA_USER].dropmax = false; +#ifdef XEN /* 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; +#endif #ifdef __HAVE_PCPU_AREA /* Per-CPU. */ @@ -1652,6 +1670,14 @@ init_slotspace(void) NBPD_L4); vm_min_kernel_address = va; vm_max_kernel_address = va + NKL4_MAX_ENTRIES * NBPD_L4; + +#ifndef XEN + /* PTE. */ + slotspace.area[SLAREA_PTE].mslot = 1; + slotspace.area[SLAREA_PTE].dropmax = false; + va = slotspace_rand(SLAREA_PTE, NBPD_L4, NBPD_L4); + pte_base = (pd_entry_t *)va; +#endif } void @@ -1675,6 +1701,8 @@ init_x86_64(paddr_t first_avail) cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0]; #endif + init_pte(); + uvm_lwp_setuarea(&lwp0, lwp0uarea); cpu_probe(&cpu_info_primary); Index: src/sys/arch/amd64/amd64/prekern.c diff -u src/sys/arch/amd64/amd64/prekern.c:1.4 src/sys/arch/amd64/amd64/prekern.c:1.5 --- src/sys/arch/amd64/amd64/prekern.c:1.4 Sun Aug 12 12:42:53 2018 +++ src/sys/arch/amd64/amd64/prekern.c Sun Aug 12 15:31:01 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: prekern.c,v 1.4 2018/08/12 12:42:53 maxv Exp $ */ +/* $NetBSD: prekern.c,v 1.5 2018/08/12 15:31:01 maxv Exp $ */ /* * Copyright (c) 2017 The NetBSD Foundation, Inc. All rights reserved. @@ -111,8 +111,20 @@ prekern_copy_args(struct prekern_args *p } static void +prekern_unmap_pte(void) +{ + extern struct bootspace bootspace; + pd_entry_t *pdir = (pd_entry_t *)bootspace.pdir; + + /* Unmap the prekern recursive PTE slot. */ + pdir[509] = 0; + tlbflushg(); +} + +static void prekern_unmap(void) { + /* Unmap the prekern itself. */ L4_BASE[0] = 0; tlbflushg(); } @@ -132,9 +144,9 @@ start_prekern(struct prekern_args *pkarg prekern_copy_args(pkargs); first_avail = pkargs->first_avail; + prekern_unmap_pte(); init_slotspace(); init_x86_64(first_avail); - prekern_unmap(); main(); Index: src/sys/arch/amd64/include/pmap.h diff -u src/sys/arch/amd64/include/pmap.h:1.52 src/sys/arch/amd64/include/pmap.h:1.53 --- src/sys/arch/amd64/include/pmap.h:1.52 Sun Aug 12 12:42:53 2018 +++ src/sys/arch/amd64/include/pmap.h Sun Aug 12 15:31:01 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.h,v 1.52 2018/08/12 12:42:53 maxv Exp $ */ +/* $NetBSD: pmap.h,v 1.53 2018/08/12 15:31:01 maxv Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -137,7 +137,11 @@ */ #define VA_SIGN_POS(va) ((va) & ~VA_SIGN_MASK) +#ifndef XEN +#define L4_SLOT_PTE slotspace.area[SLAREA_PTE].sslot +#else #define L4_SLOT_PTE 509 +#endif #define L4_SLOT_KERN slotspace.area[SLAREA_MAIN].sslot #define L4_SLOT_KERNBASE 511 /* pl4_i(KERNBASE) */ @@ -153,7 +157,12 @@ * PDP_PDE: the VA of the PDE that points back to the PDP */ +#ifndef XEN +extern pt_entry_t *pte_base; +#define PTE_BASE pte_base +#else #define PTE_BASE ((pt_entry_t *)VA_SIGN_NEG((L4_SLOT_PTE * NBPD_L4))) +#endif #define L1_BASE PTE_BASE #define L2_BASE ((pd_entry_t *)((char *)L1_BASE + L4_SLOT_PTE * NBPD_L3)) Index: src/sys/arch/x86/x86/pmap.c diff -u src/sys/arch/x86/x86/pmap.c:1.301 src/sys/arch/x86/x86/pmap.c:1.302 --- src/sys/arch/x86/x86/pmap.c:1.301 Sun Aug 12 12:42:54 2018 +++ src/sys/arch/x86/x86/pmap.c Sun Aug 12 15:31:01 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.301 2018/08/12 12:42:54 maxv Exp $ */ +/* $NetBSD: pmap.c,v 1.302 2018/08/12 15:31:01 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.301 2018/08/12 12:42:54 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.302 2018/08/12 15:31:01 maxv Exp $"); #include "opt_user_ldt.h" #include "opt_lockdebug.h" @@ -304,7 +304,11 @@ const vaddr_t ptp_masks[] = PTP_MASK_INI const int ptp_shifts[] = PTP_SHIFT_INITIALIZER; const long nkptpmax[] = NKPTPMAX_INITIALIZER; const long nbpd[] = NBPD_INITIALIZER; +#ifdef i386 pd_entry_t * const normal_pdes[] = PDES_INITIALIZER; +#else +pd_entry_t *normal_pdes[3]; +#endif long nkptp[] = NKPTP_INITIALIZER;