Index: UPDATING =================================================================== --- UPDATING +++ 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: share/man/man9/Makefile =================================================================== --- share/man/man9/Makefile +++ 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: share/man/man9/random.9 =================================================================== --- share/man/man9/random.9 +++ 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 @@ -108,6 +111,13 @@ 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 function behaves identically to .Xr read 2 Index: sys/dev/random/random_infra.c =================================================================== --- sys/dev/random/random_infra.c +++ 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(); } @@ -129,4 +141,13 @@ 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: sys/dev/random/randomdev.h =================================================================== --- sys/dev/random/randomdev.h +++ 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: sys/dev/random/randomdev.c =================================================================== --- sys/dev/random/randomdev.c +++ 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 } @@ -271,6 +274,12 @@ } } +bool +IS_RANDOM_SEEDED(void) +{ + return (p_random_alg_context->ra_seeded()); +} + static __inline void randomdev_accumulate(uint8_t *buf, u_int count) { Index: sys/sys/param.h =================================================================== --- sys/sys/param.h +++ 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: sys/sys/random.h =================================================================== --- sys/sys/random.h +++ 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) @@ -50,6 +51,11 @@ read_random(void *a __unused, u_int b __unused) { } +static __inline bool +is_random_seeded(void) +{ + return (false); +} #endif /*