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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to