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;
 

Reply via email to