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
This commit is contained in:
parent
10b1a17594
commit
f8e8a06d23
@ -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 */
|
||||
|
@ -24,9 +24,33 @@
|
||||
/*
|
||||
* 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() \
|
||||
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
@ -355,6 +360,16 @@ _elf_aux_info(int aux, void *buf, int buflen)
|
||||
} 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;
|
||||
} else
|
||||
res = EINVAL;
|
||||
break;
|
||||
default:
|
||||
res = ENOENT;
|
||||
break;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 *event)
|
||||
*/
|
||||
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,9 +132,26 @@ 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.
|
||||
*
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -1389,6 +1389,8 @@ __elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
|
||||
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);
|
||||
|
@ -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, struct sysentvec *sv2)
|
||||
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 +
|
||||
@ -305,4 +367,8 @@ exec_sysvec_init_secondary(struct sysentvec *sv, struct sysentvec *sv2)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user