Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 10 Oct 2020 21:52:00 +0000 (UTC)
From:      Conrad Meyer <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r366622 - in head: lib/libc/gen sys/amd64/amd64 sys/arm/arm sys/arm64/arm64 sys/compat/ia32 sys/dev/random/fenestrasX sys/i386/i386 sys/kern sys/mips/mips sys/powerpc/powerpc sys/riscv/...
Message-ID:  <202010102152.09ALq0js004240@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Sat Oct 10 21:52:00 2020
New Revision: 366622
URL: https://svnweb.freebsd.org/changeset/base/366622

Log:
  random(4) FenestrasX: Push root seed version to arc4random(3)
  
  Push the root seed version to userspace through the VDSO page, if
  the RANDOM_FENESTRASX algorithm is enabled.  Otherwise, there is no
  functional change.  The mechanism can be disabled with
  debug.fxrng_vdso_enable=0.
  
  arc4random(3) obtains a pointer to the root seed version published by
  the kernel in the shared page at allocation time.  Like arc4random(9),
  it maintains its own per-process copy of the seed version corresponding
  to the root seed version at the time it last rekeyed.  On read requests,
  the process seed version is compared with the version published in the
  shared page; if they do not match, arc4random(3) reseeds from the
  kernel before providing generated output.
  
  This change does not implement the FenestrasX concept of PCPU userspace
  generators seeded from a per-process base generator.  That change is
  left for future discussion/work.
  
  Reviewed by:	kib (previous version)
  Approved by:	csprng (me -- only touching FXRNG here)
  Differential Revision:	https://reviews.freebsd.org/D22839

Modified:
  head/lib/libc/gen/arc4random.c
  head/lib/libc/gen/arc4random.h
  head/lib/libc/gen/auxv.c
  head/sys/amd64/amd64/elf_machdep.c
  head/sys/arm/arm/elf_machdep.c
  head/sys/arm64/arm64/elf32_machdep.c
  head/sys/arm64/arm64/elf_machdep.c
  head/sys/compat/ia32/ia32_sysvec.c
  head/sys/dev/random/fenestrasX/fx_brng.c
  head/sys/dev/random/fenestrasX/fx_main.c
  head/sys/i386/i386/elf_machdep.c
  head/sys/kern/imgact_elf.c
  head/sys/kern/kern_sharedpage.c
  head/sys/mips/mips/elf_machdep.c
  head/sys/mips/mips/freebsd32_machdep.c
  head/sys/powerpc/powerpc/elf32_machdep.c
  head/sys/powerpc/powerpc/elf64_machdep.c
  head/sys/riscv/riscv/elf_machdep.c
  head/sys/sys/elf_common.h
  head/sys/sys/sysent.h
  head/sys/sys/vdso.h

Modified: head/lib/libc/gen/arc4random.c
==============================================================================
--- head/lib/libc/gen/arc4random.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/lib/libc/gen/arc4random.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -27,6 +27,9 @@
 __FBSDID("$FreeBSD$");
 
 #include "namespace.h"
+#if defined(__FreeBSD__)
+#include <assert.h>
+#endif
 #include <fcntl.h>
 #include <limits.h>
 #include <pthread.h>
@@ -68,6 +71,9 @@ static struct _rs {
 static struct _rsx {
 	chacha_ctx	rs_chacha;	/* chacha context for random keystream */
 	u_char		rs_buf[RSBUFSZ];	/* keystream blocks */
+#ifdef __FreeBSD__
+	uint32_t	rs_seed_generation;	/* 32-bit userspace RNG version */
+#endif
 } *rsx;
 
 static inline int _rs_allocate(struct _rs **, struct _rsx **);
@@ -96,11 +102,43 @@ _rs_stir(void)
 {
 	u_char rnd[KEYSZ + IVSZ];
 
+#if defined(__FreeBSD__)
+	bool need_init;
+
+	/*
+	 * De-couple allocation (which locates the vdso_fxrngp pointer in
+	 * auxinfo) from initialization.  This allows us to read the root seed
+	 * version before we fetch system entropy, maintaining the invariant
+	 * that the PRF was seeded with entropy from rs_seed_generation or a
+	 * later generation.  But never seeded from an earlier generation.
+	 * This invariant prevents us from missing a root reseed event.
+	 */
+	need_init = false;
+	if (rs == NULL) {
+		if (_rs_allocate(&rs, &rsx) == -1)
+			abort();
+		need_init = true;
+	}
+	/*
+	 * Transition period: new userspace on old kernel.  This should become
+	 * a hard error at some point, if the scheme is adopted.
+	 */
+	if (vdso_fxrngp != NULL)
+		rsx->rs_seed_generation =
+		    fxrng_load_acq_generation(&vdso_fxrngp->fx_generation32);
+#endif
+
 	if (getentropy(rnd, sizeof rnd) == -1)
 		_getentropy_fail();
 
+#if !defined(__FreeBSD__)
 	if (!rs)
 		_rs_init(rnd, sizeof(rnd));
+#else /* __FreeBSD__ */
+	assert(rs != NULL);
+	if (need_init)
+		_rs_init(rnd, sizeof(rnd));
+#endif
 	else
 		_rs_rekey(rnd, sizeof(rnd));
 	explicit_bzero(rnd, sizeof(rnd));	/* discard source seed */

Modified: head/lib/libc/gen/arc4random.h
==============================================================================
--- head/lib/libc/gen/arc4random.h	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/lib/libc/gen/arc4random.h	Sat Oct 10 21:52:00 2020	(r366622)
@@ -24,10 +24,34 @@
 /*
  * Stub functions for portability.
  */
+#include <sys/elf.h>
+#include <sys/endian.h>
 #include <sys/mman.h>
+#include <sys/time.h>	/* for sys/vdso.h only. */
+#include <sys/vdso.h>
+#include <machine/atomic.h>
 
+#include <err.h>
+#include <errno.h>
 #include <signal.h>
+#include <stdbool.h>
+#include <stdint.h>
 
+/*
+ * The kernel root seed version is a 64-bit counter, but we truncate it to a
+ * 32-bit value in userspace for the convenience of 32-bit platforms.  32-bit
+ * rollover is not possible with the current reseed interval (1 hour at limit)
+ * without dynamic addition of new random devices (which also force a reseed in
+ * the FXRNG design).  We don't have any dynamic device mechanism at this
+ * time, and anyway something else is very wrong if billions of new devices are
+ * being added.
+ *
+ * As is, it takes roughly 456,000 years of runtime to overflow the 32-bit
+ * version.
+ */
+#define	fxrng_load_acq_generation(x)	atomic_load_acq_32(x)
+static struct vdso_fxrng_generation_1 *vdso_fxrngp;
+
 static pthread_mutex_t	arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
 #define	_ARC4_LOCK()						\
 	do {							\
@@ -47,6 +71,28 @@ _getentropy_fail(void)
 	raise(SIGKILL);
 }
 
+static inline void
+_rs_initialize_fxrng(void)
+{
+	struct vdso_fxrng_generation_1 *fxrngp;
+	int error;
+
+	error = _elf_aux_info(AT_FXRNG, &fxrngp, sizeof(fxrngp));
+	if (error != 0) {
+		/*
+		 * New userspace on an old or !RANDOM_FENESTRASX kernel; or an
+		 * arch that does not have a VDSO page.
+		 */
+		return;
+	}
+
+	/* Old userspace on newer kernel. */
+	if (fxrngp->fx_vdso_version != VDSO_FXRNG_VER_1)
+		return;
+
+	vdso_fxrngp = fxrngp;
+}
+
 static inline int
 _rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
 {
@@ -65,12 +111,33 @@ _rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
 		return (-1);
 	}
 #endif
+
+	_rs_initialize_fxrng();
+
 	*rsp = &p->rs;
 	*rsxp = &p->rsx;
 	return (0);
 }
 
+/*
+ * This isn't only detecting fork.  We're also using the existing callback from
+ * _rs_stir_if_needed() to force arc4random(3) to reseed if the fenestrasX root
+ * seed version has changed.  (That is, the root random(4) has reseeded from
+ * pooled entropy.)
+ */
 static inline void
 _rs_forkdetect(void)
 {
+	/* Detect fork (minherit(2) INHERIT_ZERO). */
+	if (__predict_false(rs == NULL || rsx == NULL))
+		return;
+	/* If present, detect kernel FenestrasX seed version change. */
+	if (vdso_fxrngp == NULL)
+		return;
+	if (__predict_true(rsx->rs_seed_generation ==
+	    fxrng_load_acq_generation(&vdso_fxrngp->fx_generation32)))
+		return;
+
+	/* Invalidate rs_buf to force "stir" (reseed). */
+	memset(rs, 0, sizeof(*rs));
 }

Modified: head/lib/libc/gen/auxv.c
==============================================================================
--- head/lib/libc/gen/auxv.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/lib/libc/gen/auxv.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -72,6 +72,7 @@ static int hwcap_present, hwcap2_present;
 static char *canary, *pagesizes, *execpath;
 static void *ps_strings, *timekeep;
 static u_long hwcap, hwcap2;
+static void *fxrng_seed_version;
 
 #ifdef __powerpc__
 static int powerpc_new_auxv_format = 0;
@@ -139,6 +140,10 @@ init_aux(void)
 		case AT_PS_STRINGS:
 			ps_strings = aux->a_un.a_ptr;
 			break;
+
+		case AT_FXRNG:
+			fxrng_seed_version = aux->a_un.a_ptr;
+			break;
 #ifdef __powerpc__
 		/*
 		 * Since AT_STACKPROT is always set, and the common
@@ -349,6 +354,16 @@ _elf_aux_info(int aux, void *buf, int buflen)
 		if (buflen == sizeof(void *)) {
 			if (ps_strings != NULL) {
 				*(void **)buf = ps_strings;
+				res = 0;
+			} else
+				res = ENOENT;
+		} else
+			res = EINVAL;
+		break;
+	case AT_FXRNG:
+		if (buflen == sizeof(void *)) {
+			if (fxrng_seed_version != NULL) {
+				*(void **)buf = fxrng_seed_version;
 				res = 0;
 			} else
 				res = ENOENT;

Modified: head/sys/amd64/amd64/elf_machdep.c
==============================================================================
--- head/sys/amd64/amd64/elf_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/amd64/amd64/elf_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -72,7 +72,7 @@ struct sysentvec elf64_freebsd_sysvec_la48 = {
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
 	.sv_flags	= SV_ABI_FREEBSD | SV_ASLR | SV_LP64 | SV_SHP |
-			    SV_TIMEKEEP,
+			    SV_TIMEKEEP | SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,
@@ -107,7 +107,7 @@ struct sysentvec elf64_freebsd_sysvec_la57 = {
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
 	.sv_flags	= SV_ABI_FREEBSD | SV_ASLR | SV_LP64 | SV_SHP |
-			    SV_TIMEKEEP,
+			    SV_TIMEKEEP | SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: head/sys/arm/arm/elf_machdep.c
==============================================================================
--- head/sys/arm/arm/elf_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/arm/arm/elf_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -86,7 +86,7 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_maxssiz	= NULL,
 	.sv_flags	=
 #if __ARM_ARCH >= 6
-			  SV_ASLR | SV_SHP | SV_TIMEKEEP |
+			  SV_ASLR | SV_SHP | SV_TIMEKEEP | SV_RNG_SEED_VER |
 #endif
 			  SV_ABI_FREEBSD | SV_ILP32 | SV_ASLR,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,

Modified: head/sys/arm64/arm64/elf32_machdep.c
==============================================================================
--- head/sys/arm64/arm64/elf32_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/arm64/arm64/elf32_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -96,7 +96,8 @@ static struct sysentvec elf32_freebsd_sysvec = {
 	.sv_setregs	= freebsd32_setregs,
 	.sv_fixlimit	= NULL, // XXX
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_SHP | SV_TIMEKEEP,
+	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_SHP | SV_TIMEKEEP |
+	    SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = freebsd32_set_syscall_retval,
 	.sv_fetch_syscall_args = freebsd32_fetch_syscall_args,
 	.sv_syscallnames = freebsd32_syscallnames,

Modified: head/sys/arm64/arm64/elf_machdep.c
==============================================================================
--- head/sys/arm64/arm64/elf_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/arm64/arm64/elf_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -81,7 +81,7 @@ static struct sysentvec elf64_freebsd_sysvec = {
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
 	.sv_flags	= SV_SHP | SV_TIMEKEEP | SV_ABI_FREEBSD | SV_LP64 |
-	    SV_ASLR,
+	    SV_ASLR | SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: head/sys/compat/ia32/ia32_sysvec.c
==============================================================================
--- head/sys/compat/ia32/ia32_sysvec.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/compat/ia32/ia32_sysvec.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -118,7 +118,7 @@ struct sysentvec ia32_freebsd_sysvec = {
 	.sv_fixlimit	= ia32_fixlimit,
 	.sv_maxssiz	= &ia32_maxssiz,
 	.sv_flags	= SV_ABI_FREEBSD | SV_ASLR | SV_IA32 | SV_ILP32 |
-			    SV_SHP | SV_TIMEKEEP,
+			    SV_SHP | SV_TIMEKEEP | SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = ia32_set_syscall_retval,
 	.sv_fetch_syscall_args = ia32_fetch_syscall_args,
 	.sv_syscallnames = freebsd32_syscallnames,

Modified: head/sys/dev/random/fenestrasX/fx_brng.c
==============================================================================
--- head/sys/dev/random/fenestrasX/fx_brng.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/dev/random/fenestrasX/fx_brng.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sdt.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
+#include <sys/vdso.h>
 
 #include <machine/cpu.h>
 
@@ -108,6 +109,8 @@ fxrng_brng_src_reseed(const struct harvest_event *even
 	 */
 	rng->brng_generation++;
 	atomic_store_rel_64(&fxrng_root_generation, rng->brng_generation);
+	/* Update VDSO version. */
+	fxrng_push_seed_generation(rng->brng_generation);
 	FXRNG_BRNG_UNLOCK(rng);
 }
 
@@ -129,8 +132,25 @@ fxrng_brng_reseed(const void *entr, size_t sz)
 
 	rng->brng_generation++;
 	atomic_store_rel_64(&fxrng_root_generation, rng->brng_generation);
+	/* Update VDSO version. */
+	fxrng_push_seed_generation(rng->brng_generation);
 	FXRNG_BRNG_UNLOCK(rng);
 }
+
+/*
+ * Sysentvec and VDSO are initialized much later than SI_SUB_RANDOM.  When
+ * they're online, go ahead and push an initial root seed version.
+ * INIT_SYSENTVEC runs at SI_SUB_EXEC:SI_ORDER_ANY, and SI_ORDER_ANY is the
+ * maximum value, so we must run at SI_SUB_EXEC+1.
+ */
+static void
+fxrng_vdso_sysinit(void *dummy __unused)
+{
+	FXRNG_BRNG_LOCK(&fxrng_root);
+	fxrng_push_seed_generation(fxrng_root.brng_generation);
+	FXRNG_BRNG_UNLOCK(&fxrng_root);
+}
+SYSINIT(fxrng_vdso, SI_SUB_EXEC + 1, SI_ORDER_ANY, fxrng_vdso_sysinit, NULL);
 
 /*
  * Grab some bytes off an initialized, current generation RNG.

Modified: head/sys/dev/random/fenestrasX/fx_main.c
==============================================================================
--- head/sys/dev/random/fenestrasX/fx_main.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/dev/random/fenestrasX/fx_main.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -88,7 +88,8 @@
  *   a while).
  *
  * Not yet implemented, not in scope, or todo:
- *  - Userspace portions -- shared page, like timehands vdso?
+ *  - Various initial seeding sources we don't have yet
+ *  - In particular, VM migration/copy detection
  */
 
 #include <sys/cdefs.h>

Modified: head/sys/i386/i386/elf_machdep.c
==============================================================================
--- head/sys/i386/i386/elf_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/i386/i386/elf_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -74,7 +74,7 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
 	.sv_flags	= SV_ABI_FREEBSD | SV_ASLR | SV_IA32 | SV_ILP32 |
-			    SV_SHP | SV_TIMEKEEP,
+			    SV_SHP | SV_TIMEKEEP | SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/kern/imgact_elf.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -1389,6 +1389,8 @@ __elfN(freebsd_copyout_auxargs)(struct image_params *i
 	AUXARGS_ENTRY(pos, AT_ENVC, imgp->args->envc);
 	AUXARGS_ENTRY_PTR(pos, AT_ENVV, imgp->envv);
 	AUXARGS_ENTRY_PTR(pos, AT_PS_STRINGS, imgp->ps_strings);
+	if (imgp->sysent->sv_fxrng_gen_base != 0)
+		AUXARGS_ENTRY(pos, AT_FXRNG, imgp->sysent->sv_fxrng_gen_base);
 	AUXARGS_ENTRY(pos, AT_NULL, 0);
 
 	free(imgp->auxargs, M_TEMP);

Modified: head/sys/kern/kern_sharedpage.c
==============================================================================
--- head/sys/kern/kern_sharedpage.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/kern/kern_sharedpage.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/rwlock.h>
+#include <sys/stddef.h>
 #include <sys/sysent.h>
 #include <sys/sysctl.h>
 #include <sys/vdso.h>
@@ -60,6 +61,14 @@ static vm_object_t shared_page_obj;
 static int shared_page_free;
 char *shared_page_mapping;
 
+#ifdef RANDOM_FENESTRASX
+static struct vdso_fxrng_generation *fxrng_shpage_mapping;
+
+static bool fxrng_enabled = true;
+SYSCTL_BOOL(_debug, OID_AUTO, fxrng_vdso_enable, CTLFLAG_RWTUN, &fxrng_enabled,
+    0, "Enable FXRNG VDSO");
+#endif
+
 void
 shared_page_write(int base, int size, const void *data)
 {
@@ -256,10 +265,49 @@ alloc_sv_tk_compat32(void)
 }
 #endif
 
+#ifdef RANDOM_FENESTRASX
 void
+fxrng_push_seed_generation(uint64_t gen)
+{
+	if (fxrng_shpage_mapping == NULL || !fxrng_enabled)
+		return;
+	KASSERT(gen < INT32_MAX,
+	    ("fxrng seed version shouldn't roll over a 32-bit counter "
+	     "for approximately 456,000 years"));
+	atomic_store_rel_32(&fxrng_shpage_mapping->fx_generation32,
+	    (uint32_t)gen);
+}
+
+static void
+alloc_sv_fxrng_generation(void)
+{
+	int base;
+
+	/*
+	 * Allocate a full cache line for the fxrng root generation (64-bit
+	 * counter, or truncated 32-bit counter on ILP32 userspace).  It is
+	 * important that the line is not shared with frequently dirtied data,
+	 * and the shared page allocator lacks a __read_mostly mechanism.
+	 * However, PAGE_SIZE is typically large relative to the amount of
+	 * stuff we've got in it so far, so maybe the possible waste isn't an
+	 * issue.
+	 */
+	base = shared_page_alloc(CACHE_LINE_SIZE, CACHE_LINE_SIZE);
+	KASSERT(base != -1, ("%s: base allocation failed", __func__));
+	fxrng_shpage_mapping = (void *)(shared_page_mapping + base);
+	*fxrng_shpage_mapping = (struct vdso_fxrng_generation) {
+		.fx_vdso_version = VDSO_FXRNG_VER_CURR,
+	};
+}
+#endif /* RANDOM_FENESTRASX */
+
+void
 exec_sysvec_init(void *param)
 {
 	struct sysentvec *sv;
+#ifdef RANDOM_FENESTRASX
+	ptrdiff_t base;
+#endif
 
 	sv = (struct sysentvec *)param;
 	if ((sv->sv_flags & SV_SHP) == 0)
@@ -287,6 +335,18 @@ exec_sysvec_init(void *param)
 		}
 #endif
 	}
+#ifdef RANDOM_FENESTRASX
+	if ((sv->sv_flags & SV_RNG_SEED_VER) != 0) {
+		/*
+		 * Only allocate a single VDSO entry for multiple sysentvecs,
+		 * i.e., native and COMPAT32.
+		 */
+		if (fxrng_shpage_mapping == NULL)
+			alloc_sv_fxrng_generation();
+		base = (char *)fxrng_shpage_mapping - shared_page_mapping;
+		sv->sv_fxrng_gen_base = sv->sv_shared_page_base + base;
+	}
+#endif
 }
 
 void
@@ -295,6 +355,8 @@ exec_sysvec_init_secondary(struct sysentvec *sv, struc
 	MPASS((sv2->sv_flags & SV_ABI_MASK) == (sv->sv_flags & SV_ABI_MASK));
 	MPASS((sv2->sv_flags & SV_TIMEKEEP) == (sv->sv_flags & SV_TIMEKEEP));
 	MPASS((sv2->sv_flags & SV_SHP) != 0 && (sv->sv_flags & SV_SHP) != 0);
+	MPASS((sv2->sv_flags & SV_RNG_SEED_VER) ==
+	    (sv->sv_flags & SV_RNG_SEED_VER));
 
 	sv2->sv_shared_page_obj = sv->sv_shared_page_obj;
 	sv2->sv_sigcode_base = sv2->sv_shared_page_base +
@@ -304,5 +366,9 @@ exec_sysvec_init_secondary(struct sysentvec *sv, struc
 	if ((sv2->sv_flags & SV_TIMEKEEP) != 0) {
 		sv2->sv_timekeep_base = sv2->sv_shared_page_base +
 		    (sv->sv_timekeep_base - sv->sv_shared_page_base);
+	}
+	if ((sv2->sv_flags & SV_RNG_SEED_VER) != 0) {
+		sv2->sv_fxrng_gen_base = sv2->sv_shared_page_base +
+		    (sv->sv_fxrng_gen_base - sv->sv_shared_page_base);
 	}
 }

Modified: head/sys/mips/mips/elf_machdep.c
==============================================================================
--- head/sys/mips/mips/elf_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/mips/mips/elf_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -77,10 +77,11 @@ static struct sysentvec elf_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
+	.sv_flags	= SV_ABI_FREEBSD | SV_ASLR | SV_RNG_SEED_VER |
 #ifdef __mips_n64
-	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_ASLR,
+	    SV_LP64,
 #else
-	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_ASLR,
+	    SV_ILP32,
 #endif
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,

Modified: head/sys/mips/mips/freebsd32_machdep.c
==============================================================================
--- head/sys/mips/mips/freebsd32_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/mips/mips/freebsd32_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -97,7 +97,7 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32,
+	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = freebsd32_syscallnames,

Modified: head/sys/powerpc/powerpc/elf32_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/elf32_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/powerpc/powerpc/elf32_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -121,7 +121,7 @@ struct sysentvec elf32_freebsd_sysvec = {
 #endif
 	.sv_maxssiz	= NULL,
 	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_SHP | SV_ASLR |
-			    SV_TIMEKEEP,
+			    SV_TIMEKEEP | SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_shared_page_base = FREEBSD32_SHAREDPAGE,

Modified: head/sys/powerpc/powerpc/elf64_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/elf64_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/powerpc/powerpc/elf64_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -82,7 +82,7 @@ struct sysentvec elf64_freebsd_sysvec_v1 = {
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
 	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_SHP | SV_ASLR |
-			    SV_TIMEKEEP,
+			    SV_TIMEKEEP | SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,
@@ -118,7 +118,7 @@ struct sysentvec elf64_freebsd_sysvec_v2 = {
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
 	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_SHP |
-			    SV_TIMEKEEP,
+			    SV_TIMEKEEP | SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: head/sys/riscv/riscv/elf_machdep.c
==============================================================================
--- head/sys/riscv/riscv/elf_machdep.c	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/riscv/riscv/elf_machdep.c	Sat Oct 10 21:52:00 2020	(r366622)
@@ -84,7 +84,8 @@ struct sysentvec elf64_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_SHP | SV_ASLR,
+	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_SHP | SV_ASLR |
+	    SV_RNG_SEED_VER,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,

Modified: head/sys/sys/elf_common.h
==============================================================================
--- head/sys/sys/elf_common.h	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/sys/elf_common.h	Sat Oct 10 21:52:00 2020	(r366622)
@@ -967,8 +967,9 @@ typedef struct {
 #define	AT_ENVC		30	/* Environment count */
 #define	AT_ENVV		31	/* Environment vector */
 #define	AT_PS_STRINGS	32	/* struct ps_strings */
+#define	AT_FXRNG	33	/* Pointer to root RNG seed version. */
 
-#define	AT_COUNT	33	/* Count of defined aux entry types. */
+#define	AT_COUNT	34	/* Count of defined aux entry types. */
 
 /*
  * Relocation types.

Modified: head/sys/sys/sysent.h
==============================================================================
--- head/sys/sys/sysent.h	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/sys/sysent.h	Sat Oct 10 21:52:00 2020	(r366622)
@@ -144,6 +144,7 @@ struct sysentvec {
 	u_long		*sv_hwcap;	/* Value passed in AT_HWCAP. */
 	u_long		*sv_hwcap2;	/* Value passed in AT_HWCAP2. */
 	const char	*(*sv_machine_arch)(struct proc *);
+	vm_offset_t	sv_fxrng_gen_base;
 };
 
 #define	SV_ILP32	0x000100	/* 32-bit executable. */
@@ -154,6 +155,7 @@ struct sysentvec {
 #define	SV_CAPSICUM	0x020000	/* Force cap_enter() on startup. */
 #define	SV_TIMEKEEP	0x040000	/* Shared page timehands. */
 #define	SV_ASLR		0x080000	/* ASLR allowed. */
+#define	SV_RNG_SEED_VER	0x100000	/* random(4) reseed generation. */
 
 #define	SV_ABI_MASK	0xff
 #define	SV_PROC_FLAG(p, x)	((p)->p_sysent->sv_flags & (x))

Modified: head/sys/sys/vdso.h
==============================================================================
--- head/sys/sys/vdso.h	Sat Oct 10 21:48:06 2020	(r366621)
+++ head/sys/sys/vdso.h	Sat Oct 10 21:52:00 2020	(r366622)
@@ -59,6 +59,18 @@ struct vdso_timekeep {
 #define	VDSO_TH_ALGO_3		0x3
 #define	VDSO_TH_ALGO_4		0x4
 
+struct vdso_fxrng_generation_1 {
+	uint32_t	fx_vdso_version;	/* 1 */
+	uint32_t	fx_generation32;
+	uint64_t	_fx_reserved;
+};
+_Static_assert(sizeof(struct vdso_fxrng_generation_1) == 16, "");
+#define	vdso_fxrng_generation	vdso_fxrng_generation_1
+
+/* fx_vdso_version values: */
+#define	VDSO_FXRNG_VER_1	0x1
+#define	VDSO_FXRNG_VER_CURR	VDSO_FXRNG_VER_1
+
 #ifndef _KERNEL
 
 struct timespec;
@@ -82,6 +94,9 @@ struct vdso_sv_tk {
 	uint32_t	sv_timekeep_gen;
 };
 
+#ifdef RANDOM_FENESTRASX
+void fxrng_push_seed_generation(uint64_t gen);
+#endif
 void timekeep_push_vdso(void);
 
 uint32_t tc_fill_vdso_timehands(struct vdso_timehands *vdso_th);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202010102152.09ALq0js004240>