Skip to content

Commit

Permalink
random: make credit_entropy_bits() always safe
Browse files Browse the repository at this point in the history
commit a49c010 upstream.

This is called from various hwgenerator drivers, so rather than having
one "safe" version for userspace and one "unsafe" version for the
kernel, just make everything safe; the checks are cheap and sensible to
have anyway.

Reported-by: Sultan Alsawaf <sultan@kerneltoast.com>
Reviewed-by: Eric Biggers <ebiggers@google.com>
Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
zx2c4 authored and gregkh committed May 30, 2022
1 parent 32d1d7c commit b07fcd9
Showing 1 changed file with 9 additions and 20 deletions.
29 changes: 9 additions & 20 deletions drivers/char/random.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,18 +447,15 @@ static void process_random_ready_list(void)
spin_unlock_irqrestore(&random_ready_list_lock, flags);
}

/*
* Credit (or debit) the entropy store with n bits of entropy.
* Use credit_entropy_bits_safe() if the value comes from userspace
* or otherwise should be checked for extreme values.
*/
static void credit_entropy_bits(int nbits)
{
int entropy_count, orig;

if (!nbits)
if (nbits <= 0)
return;

nbits = min(nbits, POOL_BITS);

do {
orig = READ_ONCE(input_pool.entropy_count);
entropy_count = min(POOL_BITS, orig + nbits);
Expand All @@ -470,18 +467,6 @@ static void credit_entropy_bits(int nbits)
crng_reseed(&primary_crng, true);
}

static int credit_entropy_bits_safe(int nbits)
{
if (nbits < 0)
return -EINVAL;

/* Cap the value to avoid overflows */
nbits = min(nbits, POOL_BITS);

credit_entropy_bits(nbits);
return 0;
}

/*********************************************************************
*
* CRNG using CHACHA20
Expand Down Expand Up @@ -1526,7 +1511,10 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
return -EPERM;
if (get_user(ent_count, p))
return -EFAULT;
return credit_entropy_bits_safe(ent_count);
if (ent_count < 0)
return -EINVAL;
credit_entropy_bits(ent_count);
return 0;
case RNDADDENTROPY:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
Expand All @@ -1539,7 +1527,8 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
retval = write_pool((const char __user *)p, size);
if (retval < 0)
return retval;
return credit_entropy_bits_safe(ent_count);
credit_entropy_bits(ent_count);
return 0;
case RNDZAPENTCNT:
case RNDCLEARPOOL:
/*
Expand Down

0 comments on commit b07fcd9

Please sign in to comment.