Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Factor randomization out of slotspace_rand.



details:   https://anonhg.NetBSD.org/src/rev/34fa7fd7c7aa
branches:  trunk
changeset: 971900:34fa7fd7c7aa
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Fri May 08 00:49:42 2020 +0000

description:
Factor randomization out of slotspace_rand.

slotspace_rand becomes deterministic; the randomization moves into
the callers instead.  Why?

There are two callers of slotspace_rand:

- x86/pmap.c pmap_bootstrap
- amd64/amd64.c init_slotspace

When the randomization was introduced, it used an x86-only
`cpu_earlyrng' abstraction that would hash rdseed/rdrand and rdtsc
output together.  Except init_slotspace ran before cpu_probe, so
cpu_feature was not yet filled out, so during init_slotspace, the
only randomization was rdtsc.

In the course of the recent entropy overhaul, I replaced cpu_earlyrng
by entropy_extract, and moved cpu_init_rng much earlier -- but still
after cpu_probe -- in order to reduce the number of abstractions
lying around and the number of copies of rdrand/rdseed logic.  In so
doing I added some annoying complication (see curcpu_available) to
kern_entropy.c to make it work early enough for init_slotspace, and
dropped the rdtsc.

For pmap_bootstrap that didn't substantively change anything.  But
for init_slotspace, it removed the only randomization.  To mitigate
this, this commit pulls the randomization out of slotspace_rand into
pmap_bootstrap and init_slotspace, so that

(a) init_slotspace can use rdtsc and a little private entropy pool in
    order to restore the prior (weak) randomization it had, and

(b) pmap_bootstrap, which runs a little bit later, can continue to
    use entropy_extract normally and get rdrand/rdseed too.

A subsequent commit will move cpu_init_rng just a wee bit later,
after cpu_init_msrs, so the kern_entropy.c complications can go away.
Perhaps someone else more wizardly with x86 can find a way to make
init_slotspace run a little later too, after cpu_probe and after
cpu_init_msrs and after cpu_rng_init, but I am not that wizardly.

diffstat:

 sys/arch/amd64/amd64/machdep.c |  33 +++++++++++++++++++++++++++++----
 sys/arch/x86/include/pmap.h    |   4 ++--
 sys/arch/x86/x86/pmap.c        |  18 ++++++++++++------
 3 files changed, 43 insertions(+), 12 deletions(-)

diffs (163 lines):

diff -r 2d204129c231 -r 34fa7fd7c7aa sys/arch/amd64/amd64/machdep.c
--- a/sys/arch/amd64/amd64/machdep.c    Thu May 07 21:05:37 2020 +0000
+++ b/sys/arch/amd64/amd64/machdep.c    Fri May 08 00:49:42 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.352 2020/05/02 16:44:34 bouyer Exp $     */
+/*     $NetBSD: machdep.c,v 1.353 2020/05/08 00:49:42 riastradh 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.352 2020/05/02 16:44:34 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.353 2020/05/08 00:49:42 riastradh Exp $");
 
 #include "opt_modular.h"
 #include "opt_user_ldt.h"
@@ -158,6 +158,8 @@
 #include <sys/kgdb.h>
 #endif
 
+#include <lib/libkern/entpool.h> /* XXX */
+
 #include <dev/cons.h>
 #include <dev/mm.h>
 
@@ -1581,8 +1583,21 @@
 void
 init_slotspace(void)
 {
+       /*
+        * XXX Too early to use cprng(9), or even entropy_extract.
+        * Also too early to use rdrand/rdseed, since we haven't probed
+        * cpu features yet.  This is a hack -- fix me!
+        */
+       struct entpool pool;
+       size_t randhole;
+       vaddr_t randva;
+       uint64_t sample;
        vaddr_t va;
 
+       memset(&pool, 0, sizeof pool);
+       sample = rdtsc();
+       entpool_enter(&pool, &sample, sizeof sample);
+
        memset(&slotspace, 0, sizeof(slotspace));
 
        /* User. [256, because we want to land in >= 256] */
@@ -1636,16 +1651,26 @@
        slotspace.area[SLAREA_KERN].active = true;
 
        /* Main. */
+       sample = rdtsc();
+       entpool_enter(&pool, &sample, sizeof sample);
+       entpool_extract(&pool, &randhole, sizeof randhole);
+       entpool_extract(&pool, &randva, sizeof randva);
        va = slotspace_rand(SLAREA_MAIN, NKL4_MAX_ENTRIES * NBPD_L4,
-           NBPD_L4); /* TODO: NBPD_L1 */
+           NBPD_L4, randhole, randva); /* TODO: NBPD_L1 */
        vm_min_kernel_address = va;
        vm_max_kernel_address = va + NKL4_MAX_ENTRIES * NBPD_L4;
 
 #ifndef XENPV
        /* PTE. */
-       va = slotspace_rand(SLAREA_PTE, NBPD_L4, NBPD_L4);
+       sample = rdtsc();
+       entpool_enter(&pool, &sample, sizeof sample);
+       entpool_extract(&pool, &randhole, sizeof randhole);
+       entpool_extract(&pool, &randva, sizeof randva);
+       va = slotspace_rand(SLAREA_PTE, NBPD_L4, NBPD_L4, randhole, randva);
        pte_base = (pd_entry_t *)va;
 #endif
+
+       explicit_memset(&pool, 0, sizeof pool);
 }
 
 void
diff -r 2d204129c231 -r 34fa7fd7c7aa sys/arch/x86/include/pmap.h
--- a/sys/arch/x86/include/pmap.h       Thu May 07 21:05:37 2020 +0000
+++ b/sys/arch/x86/include/pmap.h       Fri May 08 00:49:42 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.119 2020/04/25 15:26:18 bouyer Exp $        */
+/*     $NetBSD: pmap.h,v 1.120 2020/05/08 00:49:42 riastradh Exp $     */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -402,7 +402,7 @@
 #ifndef __HAVE_DIRECT_MAP
 void           pmap_vpage_cpu_init(struct cpu_info *);
 #endif
-vaddr_t                slotspace_rand(int, size_t, size_t);
+vaddr_t                slotspace_rand(int, size_t, size_t, size_t, vaddr_t);
 
 vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
 
diff -r 2d204129c231 -r 34fa7fd7c7aa sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c   Thu May 07 21:05:37 2020 +0000
+++ b/sys/arch/x86/x86/pmap.c   Fri May 08 00:49:42 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.388 2020/05/05 17:02:01 bouyer Exp $        */
+/*     $NetBSD: pmap.c,v 1.389 2020/05/08 00:49:43 riastradh Exp $     */
 
 /*
  * Copyright (c) 2008, 2010, 2016, 2017, 2019, 2020 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.388 2020/05/05 17:02:01 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.389 2020/05/08 00:49:43 riastradh Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -1415,7 +1415,8 @@
  * Finally we update the associated entry in the slotspace structure.
  */
 vaddr_t
-slotspace_rand(int type, size_t sz, size_t align)
+slotspace_rand(int type, size_t sz, size_t align, size_t randhole,
+    vaddr_t randva)
 {
        struct {
                int start;
@@ -1480,7 +1481,7 @@
        }
 
        /* Select a hole. */
-       entropy_extract(&hole, sizeof(hole), 0);
+       hole = randhole;
 #ifdef NO_X86_ASLR
        hole = 0;
 #endif
@@ -1490,7 +1491,7 @@
        startva = VA_SIGN_NEG(startsl * NBPD_L4);
 
        /* Select an area within the hole. */
-       entropy_extract(&va, sizeof(va), 0);
+       va = randva;
 #ifdef NO_X86_ASLR
        va = 0;
 #endif
@@ -1619,6 +1620,8 @@
        pt_entry_t *pte;
        phys_ram_seg_t *mc;
        int i;
+       size_t randhole;
+       vaddr_t randva;
 
        const pd_entry_t pteflags = PTE_P | PTE_W | pmap_pg_nx;
        const pd_entry_t holepteflags = PTE_P | pmap_pg_nx;
@@ -1642,7 +1645,10 @@
                panic("pmap_init_directmap: lastpa incorrect");
        }
 
-       startva = slotspace_rand(SLAREA_DMAP, lastpa, NBPD_L2);
+       entropy_extract(&randhole, sizeof randhole, 0);
+       entropy_extract(&randva, sizeof randva, 0);
+       startva = slotspace_rand(SLAREA_DMAP, lastpa, NBPD_L2,
+           randhole, randva);
        endva = startva + lastpa;
 
        /* We will use this temporary va. */



Home | Main Index | Thread Index | Old Index