Index: head/UPDATING =================================================================== --- head/UPDATING +++ head/UPDATING @@ -31,6 +31,12 @@ disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20190416: + The loadable random module KPI has changed; the random_infra_init() + routine now requires a 3rd function pointer for a bool (*)(void) + method that returns true if the random device is seeded (and + therefore unblocked). + 20190404: r345895 reverts r320698. This implies that an nfsuserd(8) daemon built from head sources between r320757 (July 6, 2017) and Index: head/share/man/man9/Makefile =================================================================== --- head/share/man/man9/Makefile +++ head/share/man/man9/Makefile @@ -1668,6 +1668,7 @@ psignal.9 tdsignal.9 MLINKS+=random.9 arc4rand.9 \ random.9 arc4random.9 \ + random.9 is_random_seeded.9 \ random.9 read_random.9 \ random.9 read_random_uio.9 \ random.9 srandom.9 Index: head/share/man/man9/random.9 =================================================================== --- head/share/man/man9/random.9 +++ head/share/man/man9/random.9 @@ -26,13 +26,14 @@ .\" .\" $FreeBSD$ .\" " -.Dd April 15, 2019 +.Dd April 16, 2019 .Dt RANDOM 9 .Os .Sh NAME .Nm arc4rand , .Nm arc4random , .Nm arc4random_buf , +.Nm is_random_seeded , .Nm random , .Nm read_random , .Nm read_random_uio , @@ -48,6 +49,8 @@ .Fn arc4rand "void *ptr" "u_int length" "int reseed" .Pp .In sys/random.h +.Ft bool +.Fn is_random_seeded "void" .Ft void .Fn read_random "void *buffer" "int count" .Ft int @@ -106,6 +109,13 @@ instead, use the .Fn arc4rand family of functions. +.Pp +The +.Fn is_random_seeded +function can be used to check in advance if +.Fn read_random +will block. +(If random is seeded, it will not block.) .Pp The .Fn read_random_uio Index: head/sys/dev/random/random_infra.c =================================================================== --- head/sys/dev/random/random_infra.c +++ head/sys/dev/random/random_infra.c @@ -63,12 +63,20 @@ panic("%s: no random module is loaded", __func__); } +static bool +null_is_random_seeded(void) +{ + return (false); +} + struct random_readers { int (*read_random_uio)(struct uio *, bool); void (*read_random)(void *, u_int); + bool (*is_random_seeded)(void); } random_reader_context = { (int (*)(struct uio *, bool))nullop, null_read_random, + null_is_random_seeded, }; struct sx randomdev_config_lock; @@ -82,12 +90,15 @@ SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_FIRST, random_infra_sysinit, NULL); void -random_infra_init(int (*p_random_read_uio)(struct uio *, bool), void (*p_random_read)(void *, u_int)) +random_infra_init(int (*p_random_read_uio)(struct uio *, bool), + void (*p_random_read)(void *, u_int), + bool (*p_is_random_seeded)(void)) { RANDOM_CONFIG_X_LOCK(); random_reader_context.read_random_uio = p_random_read_uio; random_reader_context.read_random = p_random_read; + random_reader_context.is_random_seeded = p_is_random_seeded; RANDOM_CONFIG_X_UNLOCK(); } @@ -98,6 +109,7 @@ RANDOM_CONFIG_X_LOCK(); random_reader_context.read_random_uio = (int (*)(struct uio *, bool))nullop; random_reader_context.read_random = null_read_random; + random_reader_context.is_random_seeded = null_is_random_seeded; RANDOM_CONFIG_X_UNLOCK(); } @@ -128,5 +140,14 @@ random_reader_context.read_random(buf, len); RANDOM_CONFIG_S_UNLOCK(); } + +bool +is_random_seeded(void) +{ + RANDOM_CONFIG_S_LOCK(); + random_reader_context.is_random_seeded(); + RANDOM_CONFIG_S_UNLOCK(); +} + #endif /* defined(RANDOM_LOADABLE) */ Index: head/sys/dev/random/randomdev.h =================================================================== --- head/sys/dev/random/randomdev.h +++ head/sys/dev/random/randomdev.h @@ -118,7 +118,8 @@ #define RANDOM_CONFIG_S_LOCK(x) sx_slock(&randomdev_config_lock) #define RANDOM_CONFIG_S_UNLOCK(x) sx_sunlock(&randomdev_config_lock) #define RANDOM_CONFIG_DEINIT_LOCK(x) sx_destroy(&randomdev_config_lock) -void random_infra_init(int (*)(struct uio *, bool), void (*)(void *, u_int)); +void random_infra_init(int (*)(struct uio *, bool), void (*)(void *, u_int), + bool (*)(void)); void random_infra_uninit(void); #endif Index: head/sys/dev/random/randomdev.c =================================================================== --- head/sys/dev/random/randomdev.c +++ head/sys/dev/random/randomdev.c @@ -62,11 +62,14 @@ #if defined(RANDOM_LOADABLE) #define READ_RANDOM_UIO _read_random_uio #define READ_RANDOM _read_random +#define IS_RANDOM_SEEDED _is_random_seeded static int READ_RANDOM_UIO(struct uio *, bool); static void READ_RANDOM(void *, u_int); +static bool IS_RANDOM_SEEDED(void); #else #define READ_RANDOM_UIO read_random_uio #define READ_RANDOM read_random +#define IS_RANDOM_SEEDED is_random_seeded #endif static d_read_t randomdev_read; @@ -93,7 +96,7 @@ p_random_alg_context = &random_alg_context; p_random_alg_context->ra_init_alg(data); #if defined(RANDOM_LOADABLE) - random_infra_init(READ_RANDOM_UIO, READ_RANDOM); + random_infra_init(READ_RANDOM_UIO, READ_RANDOM, IS_RANDOM_SEEDED); #endif } @@ -269,6 +272,12 @@ explicit_bzero(remainder_buf, sizeof(remainder_buf)); } +} + +bool +IS_RANDOM_SEEDED(void) +{ + return (p_random_alg_context->ra_seeded()); } static __inline void Index: head/sys/sys/param.h =================================================================== --- head/sys/sys/param.h +++ head/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300018 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300019 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, Index: head/sys/sys/random.h =================================================================== --- head/sys/sys/random.h +++ head/sys/sys/random.h @@ -40,6 +40,7 @@ #if defined(DEV_RANDOM) void read_random(void *, u_int); int read_random_uio(struct uio *, bool); +bool is_random_seeded(void); #else static __inline int read_random_uio(void *a __unused, u_int b __unused) @@ -49,6 +50,11 @@ static __inline void read_random(void *a __unused, u_int b __unused) { +} +static __inline bool +is_random_seeded(void) +{ + return (false); } #endif