ACK: [SRU bionic] random: Make getrandom() ready earlier

Message ID 20180704151051.5562455.25539.20186@canonical.com
State New
Headers show
Series
  • ACK: [SRU bionic] random: Make getrandom() ready earlier
Related show

Commit Message

Khaled Elmously July 4, 2018, 3:10 p.m.
Original Message  
From: Stefan Bader
Sent: Wednesday, July 4, 2018 10:16 AM
To: kernel-team@lists.ubuntu.com
Subject: [SRU bionic] random: Make getrandom() ready earlier

From: Ben Hutchings <ben@decadent.org.uk>

This effectively reverts commit 725e828 "random: fix crng_ready()
test" which was commit 43838a23a05f upstream. Unfortunately some
users of getrandom() don't expect it to block for long, and they need
to be fixed before we can allow this change into stable.

This doesn't directly revert that commit, but only weakens the ready
condition used by getrandom() when the GRND_RANDOM flag is not set.
Calls to getrandom() that return before the RNG is fully seeded will
generate warnings, just like reads from /dev/urandom.

https://bugs.launchpad.net/bugs/1780062

(backported from ://salsa.debian.org/kernel-team/linux/raw/stretch/debian/patches/debian/random-make-getrandom-ready-earlier.patch)
[smb: open code waiting in getrandom directly]
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
---
This is based on the patch from Ben Hutchings in Debian. But since
wait_for_random_bytes, which is used in the 4.15 code is exported
and used by other things, I did instead do its own wait in getrandom().

-Stefan

drivers/char/random.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

Patch

diff --git a/drivers/char/random.c b/drivers/char/random.c
index d5f1211..6021405 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1976,10 +1976,10 @@  SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
if (flags & GRND_RANDOM)
return _random_read(flags & GRND_NONBLOCK, buf, count);

-	if (!crng_ready()) {
+	if (crng_init == 0) {
if (flags & GRND_NONBLOCK)
return -EAGAIN;
-	 ret = wait_for_random_bytes();
+	 ret = wait_event_interruptible(crng_init_wait, crng_init > 0);
if (unlikely(ret))
return ret;
}