| From 78887832e76541f77169a24ac238fccb51059b63 Mon Sep 17 00:00:00 2001 |
| From: Laurent Vivier <lvivier@redhat.com> |
| Date: Tue, 17 Sep 2019 11:54:50 +0200 |
| Subject: hwrng: core - don't wait on add_early_randomness() |
| |
| From: Laurent Vivier <lvivier@redhat.com> |
| |
| commit 78887832e76541f77169a24ac238fccb51059b63 upstream. |
| |
| add_early_randomness() is called by hwrng_register() when the |
| hardware is added. If this hardware and its module are present |
| at boot, and if there is no data available the boot hangs until |
| data are available and can't be interrupted. |
| |
| For instance, in the case of virtio-rng, in some cases the host can be |
| not able to provide enough entropy for all the guests. |
| |
| We can have two easy ways to reproduce the problem but they rely on |
| misconfiguration of the hypervisor or the egd daemon: |
| |
| - if virtio-rng device is configured to connect to the egd daemon of the |
| host but when the virtio-rng driver asks for data the daemon is not |
| connected, |
| |
| - if virtio-rng device is configured to connect to the egd daemon of the |
| host but the egd daemon doesn't provide data. |
| |
| The guest kernel will hang at boot until the virtio-rng driver provides |
| enough data. |
| |
| To avoid that, call rng_get_data() in non-blocking mode (wait=0) |
| from add_early_randomness(). |
| |
| Signed-off-by: Laurent Vivier <lvivier@redhat.com> |
| Fixes: d9e797261933 ("hwrng: add randomness to system from rng...") |
| Cc: <stable@vger.kernel.org> |
| Reviewed-by: Theodore Ts'o <tytso@mit.edu> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/char/hw_random/core.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/char/hw_random/core.c |
| +++ b/drivers/char/hw_random/core.c |
| @@ -88,7 +88,7 @@ static void add_early_randomness(struct |
| size_t size = min_t(size_t, 16, rng_buffer_size()); |
| |
| mutex_lock(&reading_mutex); |
| - bytes_read = rng_get_data(rng, rng_buffer, size, 1); |
| + bytes_read = rng_get_data(rng, rng_buffer, size, 0); |
| mutex_unlock(&reading_mutex); |
| if (bytes_read > 0) |
| add_device_randomness(rng_buffer, bytes_read); |