mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 00:21:59 +00:00
random: group userspace read/write functions
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>
This commit is contained in:
parent
92c653cf14
commit
a6adf8e7a6
@ -1477,30 +1477,61 @@ static void try_to_generate_entropy(void)
|
||||
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))
|
||||
pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
|
||||
current->comm, nbytes);
|
||||
/**********************************************************************
|
||||
*
|
||||
* Userspace reader/writer interfaces.
|
||||
*
|
||||
* 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, 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);
|
||||
return get_random_bytes_user(buf, count);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int size, ent_count;
|
||||
@ -1560,7 +1617,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
||||
|
||||
switch (cmd) {
|
||||
case RNDGETENTCNT:
|
||||
/* inherently racy, no point locking */
|
||||
/* Inherently racy, no point locking. */
|
||||
if (put_user(input_pool.entropy_count, p))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@ -1636,34 +1693,6 @@ const struct file_operations urandom_fops = {
|
||||
.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
|
||||
|
Loading…
Reference in New Issue
Block a user