Module Name: src
Committed By: riastradh
Date: Fri May 8 00:49:43 UTC 2020
Modified Files:
src/sys/arch/amd64/amd64: machdep.c
src/sys/arch/x86/include: pmap.h
src/sys/arch/x86/x86: pmap.c
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.352 -r1.353 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.119 -r1.120 src/sys/arch/x86/include/pmap.h
cvs rdiff -u -r1.388 -r1.389 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.352 src/sys/arch/amd64/amd64/machdep.c:1.353
--- src/sys/arch/amd64/amd64/machdep.c:1.352 Sat May 2 16:44:34 2020
+++ src/sys/arch/amd64/amd64/machdep.c Fri May 8 00:49:42 2020
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v
#include <sys/kgdb.h>
#endif
+#include <lib/libkern/entpool.h> /* XXX */
+
#include <dev/cons.h>
#include <dev/mm.h>
@@ -1581,8 +1583,21 @@ init_pte(void)
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 @@ init_slotspace(void)
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
Index: src/sys/arch/x86/include/pmap.h
diff -u src/sys/arch/x86/include/pmap.h:1.119 src/sys/arch/x86/include/pmap.h:1.120
--- src/sys/arch/x86/include/pmap.h:1.119 Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/include/pmap.h Fri May 8 00:49:42 2020
@@ -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 @@ void pmap_ept_transform(struct pmap *);
#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 */
Index: src/sys/arch/x86/x86/pmap.c
diff -u src/sys/arch/x86/x86/pmap.c:1.388 src/sys/arch/x86/x86/pmap.c:1.389
--- src/sys/arch/x86/x86/pmap.c:1.388 Tue May 5 17:02:01 2020
+++ src/sys/arch/x86/x86/pmap.c Fri May 8 00:49:43 2020
@@ -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 @@ slotspace_copy(int type, pd_entry_t *dst
* 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 @@ slotspace_rand(int type, size_t sz, size
}
/* Select a hole. */
- entropy_extract(&hole, sizeof(hole), 0);
+ hole = randhole;
#ifdef NO_X86_ASLR
hole = 0;
#endif
@@ -1490,7 +1491,7 @@ slotspace_rand(int type, size_t sz, size
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 @@ pmap_init_directmap(struct pmap *kpm)
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 @@ pmap_init_directmap(struct pmap *kpm)
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. */