| From edc1c90cb972fdca1f66be5a8e2b0706bd2a4949 Mon Sep 17 00:00:00 2001 |
| From: Karel Zak <kzak@redhat.com> |
| Date: Tue, 20 Mar 2018 14:17:24 +0100 |
| Subject: [PATCH] lib/randutils: don't break on EAGAIN, use usleep() |
| |
| The current code uses lose_counter to make more attempts to read |
| random numbers. It seems better to wait a moment between attempts to |
| avoid busy loop (we do the same in all-io.h). |
| |
| The worst case is 1 second delay for all random_get_bytes() on systems |
| with uninitialized entropy pool -- for example you call sfdisk (MBR Id |
| or GPT UUIDs) on very first boot, etc. In this case it will use libc |
| rand() as a fallback solution. |
| |
| Note that we do not use random numbers for security sensitive things |
| like keys or so. It's used for random based UUIDs etc. |
| |
| Addresses: https://github.com/karelzak/util-linux/pull/603 |
| Signed-off-by: Karel Zak <kzak@redhat.com> |
| Signed-off-by: Peter Korsgaard <peter@korsgaard.com> |
| --- |
| lib/randutils.c | 17 ++++++++++++----- |
| 1 file changed, 12 insertions(+), 5 deletions(-) |
| |
| diff --git a/lib/randutils.c b/lib/randutils.c |
| index 02c3d9eb0..de4279530 100644 |
| --- a/lib/randutils.c |
| +++ b/lib/randutils.c |
| @@ -95,6 +95,9 @@ int random_get_fd(void) |
| * Use /dev/urandom if possible, and if not, |
| * use glibc pseudo-random functions. |
| */ |
| +#define UL_RAND_READ_ATTEMPTS 8 |
| +#define UL_RAND_READ_DELAY 125000 /* microseconds */ |
| + |
| void random_get_bytes(void *buf, size_t nbytes) |
| { |
| unsigned char *cp = (unsigned char *)buf; |
| @@ -111,11 +114,14 @@ void random_get_bytes(void *buf, size_t nbytes) |
| n -= x; |
| cp += x; |
| lose_counter = 0; |
| - } else if (errno == ENOSYS) /* kernel without getrandom() */ |
| - break; |
| - else if (errno == EAGAIN) |
| + |
| + } else if (errno == ENOSYS) { /* kernel without getrandom() */ |
| break; |
| - else if (lose_counter++ > 16) /* entropy problem? */ |
| + |
| + } else if (errno == EAGAIN && lose_counter < UL_RAND_READ_ATTEMPTS) { |
| + xusleep(UL_RAND_READ_DELAY); /* no etropy, wait and try again */ |
| + lose_counter++; |
| + } else |
| break; |
| } |
| |
| @@ -134,8 +140,9 @@ void random_get_bytes(void *buf, size_t nbytes) |
| while (n > 0) { |
| ssize_t x = read(fd, cp, n); |
| if (x <= 0) { |
| - if (lose_counter++ > 16) |
| + if (lose_counter++ > UL_RAND_READ_ATTEMPTS) |
| break; |
| + xusleep(UL_RAND_READ_DELAY); |
| continue; |
| } |
| n -= x; |
| -- |
| 2.11.0 |
| |