Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch More ASLR: randomize the location of the PTE area. ...



details:   https://anonhg.NetBSD.org/src/rev/c2678d4b22e2
branches:  trunk
changeset: 834420:c2678d4b22e2
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sun Aug 12 15:31:01 2018 +0000

description:
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.

diffstat:

 sys/arch/amd64/amd64/genassym.cf |   4 +---
 sys/arch/amd64/amd64/locore.S    |   9 +--------
 sys/arch/amd64/amd64/machdep.c   |  32 ++++++++++++++++++++++++++++++--
 sys/arch/amd64/amd64/prekern.c   |  16 ++++++++++++++--
 sys/arch/amd64/include/pmap.h    |  11 ++++++++++-
 sys/arch/x86/x86/pmap.c          |   8 ++++++--
 6 files changed, 62 insertions(+), 18 deletions(-)

diffs (233 lines):

diff -r 0204f1944965 -r c2678d4b22e2 sys/arch/amd64/amd64/genassym.cf
--- a/sys/arch/amd64/amd64/genassym.cf  Sun Aug 12 15:05:13 2018 +0000
+++ b/sys/arch/amd64/amd64/genassym.cf  Sun Aug 12 15:31:01 2018 +0000
@@ -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 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
diff -r 0204f1944965 -r c2678d4b22e2 sys/arch/amd64/amd64/locore.S
--- a/sys/arch/amd64/amd64/locore.S     Sun Aug 12 15:05:13 2018 +0000
+++ b/sys/arch/amd64/amd64/locore.S     Sun Aug 12 15:31:01 2018 +0000
@@ -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 @@
        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).
diff -r 0204f1944965 -r c2678d4b22e2 sys/arch/amd64/amd64/machdep.c
--- a/sys/arch/amd64/amd64/machdep.c    Sun Aug 12 15:05:13 2018 +0000
+++ b/sys/arch/amd64/amd64/machdep.c    Sun Aug 12 15:31:01 2018 +0000
@@ -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 @@
 
 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 @@
        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 @@
        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 @@
            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 @@
        cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
 #endif
 
+       init_pte();
+
        uvm_lwp_setuarea(&lwp0, lwp0uarea);
 
        cpu_probe(&cpu_info_primary);
diff -r 0204f1944965 -r c2678d4b22e2 sys/arch/amd64/amd64/prekern.c
--- a/sys/arch/amd64/amd64/prekern.c    Sun Aug 12 15:05:13 2018 +0000
+++ b/sys/arch/amd64/amd64/prekern.c    Sun Aug 12 15:31:01 2018 +0000
@@ -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 @@
 }
 
 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 @@
        prekern_copy_args(pkargs);
        first_avail = pkargs->first_avail;
 
+       prekern_unmap_pte();
        init_slotspace();
        init_x86_64(first_avail);
-
        prekern_unmap();
 
        main();
diff -r 0204f1944965 -r c2678d4b22e2 sys/arch/amd64/include/pmap.h
--- a/sys/arch/amd64/include/pmap.h     Sun Aug 12 15:05:13 2018 +0000
+++ b/sys/arch/amd64/include/pmap.h     Sun Aug 12 15:31:01 2018 +0000
@@ -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))
diff -r 0204f1944965 -r c2678d4b22e2 sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c   Sun Aug 12 15:05:13 2018 +0000
+++ b/sys/arch/x86/x86/pmap.c   Sun Aug 12 15:31:01 2018 +0000
@@ -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 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;
 



Home | Main Index | Thread Index | Old Index