drivers/char/random.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 566922df4b7b..7be771eac969 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -2118,6 +2118,37 @@ const struct file_operations urandom_fops = { .llseek = noop_llseek, }; +/* + * Hacky workaround for the fact that some processes + * ask for truly secure random numbers and absolutely want + * to wait for the entropy pool to fill, and others just + * do "getrandom(0)" to get some ad-hoc random numbers. + * + * If you're generating a secure key, you'd better ask for + * more than 128 bits of randomness. Otherwise it's not + * really all that secure by definition. + * + * We should add a GRND_SECURE flag so that people can state + * this "I want secure random numbers" explicitly. + */ +static int wait_for_getrandom(size_t count) +{ + unsigned long timeout = MAX_SCHEDULE_TIMEOUT; + int ret; + + /* We'll give even small requests _some_ time to get more entropy */ + if (count <= 16) + timeout = 5*HZ; + + ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), timeout); + if (likely(ret)) + return ret > 0 ? 0 : ret; + + /* Timed out - we'll return urandom */ + pr_notice("random: falling back to urandom for small request of %zu bytes", count); + return 0; +} + SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int, flags) { @@ -2135,7 +2166,7 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, if (!crng_ready()) { if (flags & GRND_NONBLOCK) return -EAGAIN; - ret = wait_for_random_bytes(); + ret = wait_for_getrandom(count); if (unlikely(ret)) return ret; }