| From foo@baz Fri Jun 17 08:58:56 AM CEST 2022 |
| From: Andy Lutomirski <luto@kernel.org> |
| Date: Mon, 23 Dec 2019 00:20:48 -0800 |
| Subject: random: make /dev/random be almost like /dev/urandom |
| |
| From: Andy Lutomirski <luto@kernel.org> |
| |
| commit 30c08efec8884fb106b8e57094baa51bb4c44e32 upstream. |
| |
| This patch changes the read semantics of /dev/random to be the same |
| as /dev/urandom except that reads will block until the CRNG is |
| ready. |
| |
| None of the cleanups that this enables have been done yet. As a |
| result, this gives a warning about an unused function. |
| |
| Signed-off-by: Andy Lutomirski <luto@kernel.org> |
| Link: https://lore.kernel.org/r/5e6ac8831c6cf2e56a7a4b39616d1732b2bdd06c.1577088521.git.luto@kernel.org |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/char/random.c | 54 ++++++++++++-------------------------------------- |
| 1 file changed, 13 insertions(+), 41 deletions(-) |
| |
| --- a/drivers/char/random.c |
| +++ b/drivers/char/random.c |
| @@ -354,7 +354,6 @@ |
| #define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5)) |
| #define OUTPUT_POOL_SHIFT 10 |
| #define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5)) |
| -#define SEC_XFER_SIZE 512 |
| #define EXTRACT_SIZE 10 |
| |
| |
| @@ -804,7 +803,6 @@ retry: |
| if (entropy_bits >= random_read_wakeup_bits && |
| wq_has_sleeper(&random_read_wait)) { |
| wake_up_interruptible(&random_read_wait); |
| - kill_fasync(&fasync, SIGIO, POLL_IN); |
| } |
| /* If the input pool is getting full, and the blocking |
| * pool has room, send some entropy to the blocking |
| @@ -1988,43 +1986,6 @@ void rand_initialize_disk(struct gendisk |
| #endif |
| |
| static ssize_t |
| -_random_read(int nonblock, char __user *buf, size_t nbytes) |
| -{ |
| - ssize_t n; |
| - |
| - if (nbytes == 0) |
| - return 0; |
| - |
| - nbytes = min_t(size_t, nbytes, SEC_XFER_SIZE); |
| - while (1) { |
| - n = extract_entropy_user(&blocking_pool, buf, nbytes); |
| - if (n < 0) |
| - return n; |
| - trace_random_read(n*8, (nbytes-n)*8, |
| - ENTROPY_BITS(&blocking_pool), |
| - ENTROPY_BITS(&input_pool)); |
| - if (n > 0) |
| - return n; |
| - |
| - /* Pool is (near) empty. Maybe wait and retry. */ |
| - if (nonblock) |
| - return -EAGAIN; |
| - |
| - wait_event_interruptible(random_read_wait, |
| - blocking_pool.initialized && |
| - (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits)); |
| - if (signal_pending(current)) |
| - return -ERESTARTSYS; |
| - } |
| -} |
| - |
| -static ssize_t |
| -random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
| -{ |
| - return _random_read(file->f_flags & O_NONBLOCK, buf, nbytes); |
| -} |
| - |
| -static ssize_t |
| urandom_read_nowarn(struct file *file, char __user *buf, size_t nbytes, |
| loff_t *ppos) |
| { |
| @@ -2056,15 +2017,26 @@ urandom_read(struct file *file, char __u |
| return urandom_read_nowarn(file, buf, nbytes, ppos); |
| } |
| |
| +static ssize_t |
| +random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
| +{ |
| + int ret; |
| + |
| + ret = wait_for_random_bytes(); |
| + if (ret != 0) |
| + return ret; |
| + return urandom_read_nowarn(file, buf, nbytes, ppos); |
| +} |
| + |
| static __poll_t |
| random_poll(struct file *file, poll_table * wait) |
| { |
| __poll_t mask; |
| |
| - poll_wait(file, &random_read_wait, wait); |
| + poll_wait(file, &crng_init_wait, wait); |
| poll_wait(file, &random_write_wait, wait); |
| mask = 0; |
| - if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits) |
| + if (crng_ready()) |
| mask |= EPOLLIN | EPOLLRDNORM; |
| if (ENTROPY_BITS(&input_pool) < random_write_wakeup_bits) |
| mask |= EPOLLOUT | EPOLLWRNORM; |