diff --git a/UPDATING b/UPDATING index a4864d1b45d5..d909a17396b0 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW: 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 diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 6eb5ee9e7983..863a1135f5a6 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1668,6 +1668,7 @@ MLINKS+=psignal.9 gsignal.9 \ 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 diff --git a/share/man/man9/random.9 b/share/man/man9/random.9 index 2e6189790412..97218dcab39c 100644 --- a/share/man/man9/random.9 +++ b/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 @@ instead, use the 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 diff --git a/sys/dev/random/random_infra.c b/sys/dev/random/random_infra.c index 324c40dcecd4..59cd44280b95 100644 --- a/sys/dev/random/random_infra.c +++ b/sys/dev/random/random_infra.c @@ -63,12 +63,20 @@ null_read_random(void *dummy __unused, u_int dummy2 __unused) 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 @@ random_infra_sysinit(void *dummy __unused) 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_infra_uninit(void) 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 @@ read_random(void *buf, u_int 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) */ diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c index 19a73b28151a..cbe01d1c5343 100644 --- a/sys/dev/random/randomdev.c +++ b/sys/dev/random/randomdev.c @@ -62,11 +62,14 @@ __FBSDID("$FreeBSD$"); #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 @@ random_alg_context_ra_init_alg(void *data) 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 @@ READ_RANDOM(void *random_buf, u_int len) } } +bool +IS_RANDOM_SEEDED(void) +{ + return (p_random_alg_context->ra_seeded()); +} + static __inline void randomdev_accumulate(uint8_t *buf, u_int count) { diff --git a/sys/dev/random/randomdev.h b/sys/dev/random/randomdev.h index 41300f237aaf..e5df7efefa5b 100644 --- a/sys/dev/random/randomdev.h +++ b/sys/dev/random/randomdev.h @@ -118,7 +118,8 @@ extern struct sx randomdev_config_lock; #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 diff --git a/sys/sys/param.h b/sys/sys/param.h index 8dc3686027bd..ddc59bf64373 100644 --- a/sys/sys/param.h +++ b/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, diff --git a/sys/sys/random.h b/sys/sys/random.h index 8a9cbf49ccbd..aa8c5f02c32e 100644 --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -40,6 +40,7 @@ struct uio; #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 @@ static __inline void read_random(void *a __unused, u_int b __unused) { } +static __inline bool +is_random_seeded(void) +{ + return (false); +} #endif /*