From: "Jason A. Donenfeld" Jason@zx2c4.com
commit 7b5164fb1279bf0251371848e40bae646b59b3a8 upstream.
This buffer may contain entropic data that shouldn't stick around longer than needed, so zero out the temporary buffer at the end of write_pool().
Reviewed-by: Dominik Brodowski linux@dominikbrodowski.net Reviewed-by: Jann Horn jannh@google.com Reviewed-by: Eric Biggers ebiggers@google.com Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/random.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -552,6 +552,7 @@ static void crng_reseed(void) int entropy_count; unsigned long next_gen; u8 key[CHACHA20_KEY_SIZE]; + bool finalize_init = false;
/* * First we make sure we have POOL_MIN_BITS of entropy in the pool, @@ -579,12 +580,14 @@ static void crng_reseed(void) ++next_gen; WRITE_ONCE(base_crng.generation, next_gen); WRITE_ONCE(base_crng.birth, jiffies); - spin_unlock_irqrestore(&base_crng.lock, flags); - memzero_explicit(key, sizeof(key)); - if (crng_init < 2) { invalidate_batched_entropy(); crng_init = 2; + finalize_init = true; + } + spin_unlock_irqrestore(&base_crng.lock, flags); + memzero_explicit(key, sizeof(key)); + if (finalize_init) { process_random_ready_list(); wake_up_interruptible(&crng_init_wait); kill_fasync(&fasync, SIGIO, POLL_IN); @@ -1386,19 +1389,24 @@ static unsigned int random_poll(struct f static int write_pool(const char __user *ubuf, size_t count) { size_t len; + int ret = 0; u8 block[BLAKE2S_BLOCK_SIZE];
while (count) { len = min(count, sizeof(block)); - if (copy_from_user(block, ubuf, len)) - return -EFAULT; + if (copy_from_user(block, ubuf, len)) { + ret = -EFAULT; + goto out; + } count -= len; ubuf += len; mix_pool_bytes(block, len); cond_resched(); }
- return 0; +out: + memzero_explicit(block, sizeof(block)); + return ret; }
static ssize_t random_write(struct file *file, const char __user *buffer,