random: group userspace read/write functions
commit a6adf8e7a605250b911e94793fd077933709ff9e upstream. This pulls all of the userspace read/write-focused functions into the fifth labeled section. No functional changes. Cc: Theodore Ts'o <tytso@mit.edu> 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>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
f04580811d
commit
21ae543e3a
@@ -1477,30 +1477,61 @@ static void try_to_generate_entropy(void)
|
|||||||
mix_pool_bytes(&stack.now, sizeof(stack.now));
|
mix_pool_bytes(&stack.now, sizeof(stack.now));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t urandom_read(struct file *file, char __user *buf, size_t nbytes,
|
|
||||||
loff_t *ppos)
|
|
||||||
{
|
|
||||||
static int maxwarn = 10;
|
|
||||||
|
|
||||||
if (!crng_ready() && maxwarn > 0) {
|
/**********************************************************************
|
||||||
maxwarn--;
|
*
|
||||||
if (__ratelimit(&urandom_warning))
|
* Userspace reader/writer interfaces.
|
||||||
pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
|
*
|
||||||
current->comm, nbytes);
|
* getrandom(2) is the primary modern interface into the RNG and should
|
||||||
|
* be used in preference to anything else.
|
||||||
|
*
|
||||||
|
* Reading from /dev/random has the same functionality as calling
|
||||||
|
* getrandom(2) with flags=0. In earlier versions, however, it had
|
||||||
|
* vastly different semantics and should therefore be avoided, to
|
||||||
|
* prevent backwards compatibility issues.
|
||||||
|
*
|
||||||
|
* Reading from /dev/urandom has the same functionality as calling
|
||||||
|
* getrandom(2) with flags=GRND_INSECURE. Because it does not block
|
||||||
|
* waiting for the RNG to be ready, it should not be used.
|
||||||
|
*
|
||||||
|
* Writing to either /dev/random or /dev/urandom adds entropy to
|
||||||
|
* the input pool but does not credit it.
|
||||||
|
*
|
||||||
|
* Polling on /dev/random indicates when the RNG is initialized, on
|
||||||
|
* the read side, and when it wants new entropy, on the write side.
|
||||||
|
*
|
||||||
|
* Both /dev/random and /dev/urandom have the same set of ioctls for
|
||||||
|
* adding entropy, getting the entropy count, zeroing the count, and
|
||||||
|
* reseeding the crng.
|
||||||
|
*
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int,
|
||||||
|
flags)
|
||||||
|
{
|
||||||
|
if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Requesting insecure and blocking randomness at the same time makes
|
||||||
|
* no sense.
|
||||||
|
*/
|
||||||
|
if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (count > INT_MAX)
|
||||||
|
count = INT_MAX;
|
||||||
|
|
||||||
|
if (!(flags & GRND_INSECURE) && !crng_ready()) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (flags & GRND_NONBLOCK)
|
||||||
|
return -EAGAIN;
|
||||||
|
ret = wait_for_random_bytes();
|
||||||
|
if (unlikely(ret))
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
return get_random_bytes_user(buf, count);
|
||||||
return get_random_bytes_user(buf, nbytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 get_random_bytes_user(buf, nbytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __poll_t random_poll(struct file *file, poll_table *wait)
|
static __poll_t random_poll(struct file *file, poll_table *wait)
|
||||||
@@ -1552,6 +1583,32 @@ static ssize_t random_write(struct file *file, const char __user *buffer,
|
|||||||
return (ssize_t)count;
|
return (ssize_t)count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t urandom_read(struct file *file, char __user *buf, size_t nbytes,
|
||||||
|
loff_t *ppos)
|
||||||
|
{
|
||||||
|
static int maxwarn = 10;
|
||||||
|
|
||||||
|
if (!crng_ready() && maxwarn > 0) {
|
||||||
|
maxwarn--;
|
||||||
|
if (__ratelimit(&urandom_warning))
|
||||||
|
pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
|
||||||
|
current->comm, nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_random_bytes_user(buf, nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 get_random_bytes_user(buf, nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
int size, ent_count;
|
int size, ent_count;
|
||||||
@@ -1560,7 +1617,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
|||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case RNDGETENTCNT:
|
case RNDGETENTCNT:
|
||||||
/* inherently racy, no point locking */
|
/* Inherently racy, no point locking. */
|
||||||
if (put_user(input_pool.entropy_count, p))
|
if (put_user(input_pool.entropy_count, p))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1636,34 +1693,6 @@ const struct file_operations urandom_fops = {
|
|||||||
.llseek = noop_llseek,
|
.llseek = noop_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int,
|
|
||||||
flags)
|
|
||||||
{
|
|
||||||
if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Requesting insecure and blocking randomness at the same time makes
|
|
||||||
* no sense.
|
|
||||||
*/
|
|
||||||
if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (count > INT_MAX)
|
|
||||||
count = INT_MAX;
|
|
||||||
|
|
||||||
if (!(flags & GRND_INSECURE) && !crng_ready()) {
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (flags & GRND_NONBLOCK)
|
|
||||||
return -EAGAIN;
|
|
||||||
ret = wait_for_random_bytes();
|
|
||||||
if (unlikely(ret))
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return get_random_bytes_user(buf, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
*
|
*
|
||||||
* Sysctl interface
|
* Sysctl interface
|
||||||
|
Reference in New Issue
Block a user