random: convert to using fops->write_iter()
Now that the read side has been converted to fix a regression with splice, convert the write side as well to have some symmetry in the interface used (and help deprecate ->write()). Signed-off-by: Jens Axboe <axboe@kernel.dk> [Jason: cleaned up random_ioctl a bit, require full writes in RNDADDENTROPY since it's crediting entropy, simplify control flow of write_pool(), and incorporate suggestions from Al.] Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
1b388e7765
commit
22b0a222af
|
@ -1274,39 +1274,31 @@ static __poll_t random_poll(struct file *file, poll_table *wait)
|
|||
return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
|
||||
}
|
||||
|
||||
static int write_pool(const char __user *ubuf, size_t len)
|
||||
static ssize_t write_pool(struct iov_iter *iter)
|
||||
{
|
||||
size_t block_len;
|
||||
int ret = 0;
|
||||
u8 block[BLAKE2S_BLOCK_SIZE];
|
||||
ssize_t ret = 0;
|
||||
size_t copied;
|
||||
|
||||
while (len) {
|
||||
block_len = min(len, sizeof(block));
|
||||
if (copy_from_user(block, ubuf, block_len)) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
len -= block_len;
|
||||
ubuf += block_len;
|
||||
mix_pool_bytes(block, block_len);
|
||||
if (unlikely(!iov_iter_count(iter)))
|
||||
return 0;
|
||||
|
||||
for (;;) {
|
||||
copied = copy_from_iter(block, sizeof(block), iter);
|
||||
ret += copied;
|
||||
mix_pool_bytes(block, copied);
|
||||
if (!iov_iter_count(iter) || copied != sizeof(block))
|
||||
break;
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
out:
|
||||
memzero_explicit(block, sizeof(block));
|
||||
return ret;
|
||||
return ret ? ret : -EFAULT;
|
||||
}
|
||||
|
||||
static ssize_t random_write(struct file *file, const char __user *ubuf,
|
||||
size_t len, loff_t *ppos)
|
||||
static ssize_t random_write_iter(struct kiocb *kiocb, struct iov_iter *iter)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = write_pool(ubuf, len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return (ssize_t)len;
|
||||
return write_pool(iter);
|
||||
}
|
||||
|
||||
static ssize_t urandom_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
|
||||
|
@ -1345,9 +1337,8 @@ static ssize_t random_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
|
|||
|
||||
static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int size, ent_count;
|
||||
int __user *p = (int __user *)arg;
|
||||
int retval;
|
||||
int ent_count;
|
||||
|
||||
switch (cmd) {
|
||||
case RNDGETENTCNT:
|
||||
|
@ -1364,20 +1355,32 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
|||
return -EINVAL;
|
||||
credit_init_bits(ent_count);
|
||||
return 0;
|
||||
case RNDADDENTROPY:
|
||||
case RNDADDENTROPY: {
|
||||
struct iov_iter iter;
|
||||
struct iovec iov;
|
||||
ssize_t ret;
|
||||
int len;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
if (get_user(ent_count, p++))
|
||||
return -EFAULT;
|
||||
if (ent_count < 0)
|
||||
return -EINVAL;
|
||||
if (get_user(size, p++))
|
||||
if (get_user(len, p++))
|
||||
return -EFAULT;
|
||||
ret = import_single_range(WRITE, p, len, &iov, &iter);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
ret = write_pool(&iter);
|
||||
if (unlikely(ret < 0))
|
||||
return ret;
|
||||
/* Since we're crediting, enforce that it was all written into the pool. */
|
||||
if (unlikely(ret != len))
|
||||
return -EFAULT;
|
||||
retval = write_pool((const char __user *)p, size);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
credit_init_bits(ent_count);
|
||||
return 0;
|
||||
}
|
||||
case RNDZAPENTCNT:
|
||||
case RNDCLEARPOOL:
|
||||
/* No longer has any effect. */
|
||||
|
@ -1403,7 +1406,7 @@ static int random_fasync(int fd, struct file *filp, int on)
|
|||
|
||||
const struct file_operations random_fops = {
|
||||
.read_iter = random_read_iter,
|
||||
.write = random_write,
|
||||
.write_iter = random_write_iter,
|
||||
.poll = random_poll,
|
||||
.unlocked_ioctl = random_ioctl,
|
||||
.compat_ioctl = compat_ptr_ioctl,
|
||||
|
@ -1413,7 +1416,7 @@ const struct file_operations random_fops = {
|
|||
|
||||
const struct file_operations urandom_fops = {
|
||||
.read_iter = urandom_read_iter,
|
||||
.write = random_write,
|
||||
.write_iter = random_write_iter,
|
||||
.unlocked_ioctl = random_ioctl,
|
||||
.compat_ioctl = compat_ptr_ioctl,
|
||||
.fasync = random_fasync,
|
||||
|
|
Loading…
Reference in New Issue