All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] random: Jens' {read,write}_iter respin
@ 2022-05-20  0:40 Jason A. Donenfeld
  2022-05-20  0:40 ` [PATCH v3 1/3] random: convert to using fops->read_iter() Jason A. Donenfeld
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Jason A. Donenfeld @ 2022-05-20  0:40 UTC (permalink / raw)
  To: Jens Axboe, LKML; +Cc: Jason A. Donenfeld

Hey Jens,

Here's what I've done to your patches. Could you let me know if I've
mangled anything in the process?

Jason

Jens Axboe (3):
  random: convert to using fops->read_iter()
  random: convert to using fops->write_iter()
  random: wire up fops->splice_{read,write}_iter()

 drivers/char/random.c | 121 ++++++++++++++++++++++--------------------
 1 file changed, 63 insertions(+), 58 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/3] random: convert to using fops->read_iter()
  2022-05-20  0:40 [PATCH v3 0/3] random: Jens' {read,write}_iter respin Jason A. Donenfeld
@ 2022-05-20  0:40 ` Jason A. Donenfeld
  2022-05-20  1:11   ` Jens Axboe
  2022-05-20  0:40 ` [PATCH v3 2/3] random: convert to using fops->write_iter() Jason A. Donenfeld
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Jason A. Donenfeld @ 2022-05-20  0:40 UTC (permalink / raw)
  To: Jens Axboe, LKML; +Cc: Jason A . Donenfeld

From: Jens Axboe <axboe@kernel.dk>

This is a pre-requisite to writing up splice() again for the random
and urandom drivers.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
[Jason: simplify control flow a bit in get_random_bytes_user().]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/char/random.c | 49 ++++++++++++++++++++-----------------------
 1 file changed, 23 insertions(+), 26 deletions(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0958fa91a964..2b2c3681f172 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -397,13 +397,13 @@ void get_random_bytes(void *buf, size_t len)
 }
 EXPORT_SYMBOL(get_random_bytes);
 
-static ssize_t get_random_bytes_user(void __user *ubuf, size_t len)
+static ssize_t get_random_bytes_user(struct iov_iter *to)
 {
-	size_t block_len, left, ret = 0;
 	u32 chacha_state[CHACHA_STATE_WORDS];
 	u8 output[CHACHA_BLOCK_SIZE];
+	size_t ret = 0;
 
-	if (!len)
+	if (!iov_iter_count(to))
 		return 0;
 
 	/*
@@ -417,27 +417,21 @@ static ssize_t get_random_bytes_user(void __user *ubuf, size_t len)
 	 * use chacha_state after, so we can simply return those bytes to
 	 * the user directly.
 	 */
-	if (len <= CHACHA_KEY_SIZE) {
-		ret = len - copy_to_user(ubuf, &chacha_state[4], len);
+	if (iov_iter_count(to) <= CHACHA_KEY_SIZE) {
+		ret = copy_to_iter(&chacha_state[4], iov_iter_count(to), to);
 		goto out_zero_chacha;
 	}
 
 	for (;;) {
+		size_t copied, block_len = min_t(size_t, iov_iter_count(to), CHACHA_BLOCK_SIZE);
+
 		chacha20_block(chacha_state, output);
 		if (unlikely(chacha_state[12] == 0))
 			++chacha_state[13];
 
-		block_len = min_t(size_t, len, CHACHA_BLOCK_SIZE);
-		left = copy_to_user(ubuf, output, block_len);
-		if (left) {
-			ret += block_len - left;
-			break;
-		}
-
-		ubuf += block_len;
-		ret += block_len;
-		len -= block_len;
-		if (!len)
+		copied = copy_to_iter(output, block_len, to);
+		ret += copied;
+		if (!iov_iter_count(to) || copied != block_len)
 			break;
 
 		BUILD_BUG_ON(PAGE_SIZE % CHACHA_BLOCK_SIZE != 0);
@@ -1248,6 +1242,9 @@ static void __cold try_to_generate_entropy(void)
 
 SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags)
 {
+	struct iovec iov = { .iov_base = ubuf };
+	struct iov_iter iter;
+
 	if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
 		return -EINVAL;
 
@@ -1270,7 +1267,9 @@ SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags
 		if (unlikely(ret))
 			return ret;
 	}
-	return get_random_bytes_user(ubuf, len);
+	iov.iov_len = len;
+	iov_iter_init(&iter, READ, &iov, 1, len);
+	return get_random_bytes_user(&iter);
 }
 
 static __poll_t random_poll(struct file *file, poll_table *wait)
@@ -1314,8 +1313,7 @@ static ssize_t random_write(struct file *file, const char __user *ubuf,
 	return (ssize_t)len;
 }
 
-static ssize_t urandom_read(struct file *file, char __user *ubuf,
-			    size_t len, loff_t *ppos)
+static ssize_t urandom_read_iter(struct kiocb *kiocb, struct iov_iter *to)
 {
 	static int maxwarn = 10;
 
@@ -1332,22 +1330,21 @@ static ssize_t urandom_read(struct file *file, char __user *ubuf,
 		else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
 			--maxwarn;
 			pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
-				  current->comm, len);
+				  current->comm, iov_iter_count(to));
 		}
 	}
 
-	return get_random_bytes_user(ubuf, len);
+	return get_random_bytes_user(to);
 }
 
-static ssize_t random_read(struct file *file, char __user *ubuf,
-			   size_t len, loff_t *ppos)
+static ssize_t random_read_iter(struct kiocb *kiocb, struct iov_iter *to)
 {
 	int ret;
 
 	ret = wait_for_random_bytes();
 	if (ret != 0)
 		return ret;
-	return get_random_bytes_user(ubuf, len);
+	return get_random_bytes_user(to);
 }
 
 static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
@@ -1409,7 +1406,7 @@ static int random_fasync(int fd, struct file *filp, int on)
 }
 
 const struct file_operations random_fops = {
-	.read = random_read,
+	.read_iter = random_read_iter,
 	.write = random_write,
 	.poll = random_poll,
 	.unlocked_ioctl = random_ioctl,
@@ -1419,7 +1416,7 @@ const struct file_operations random_fops = {
 };
 
 const struct file_operations urandom_fops = {
-	.read = urandom_read,
+	.read_iter = urandom_read_iter,
 	.write = random_write,
 	.unlocked_ioctl = random_ioctl,
 	.compat_ioctl = compat_ptr_ioctl,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/3] random: convert to using fops->write_iter()
  2022-05-20  0:40 [PATCH v3 0/3] random: Jens' {read,write}_iter respin Jason A. Donenfeld
  2022-05-20  0:40 ` [PATCH v3 1/3] random: convert to using fops->read_iter() Jason A. Donenfeld
@ 2022-05-20  0:40 ` Jason A. Donenfeld
  2022-05-20  0:40 ` [PATCH v3 3/3] random: wire up fops->splice_{read,write}_iter() Jason A. Donenfeld
  2022-05-20  1:11 ` [PATCH v3 0/3] random: Jens' {read,write}_iter respin Jens Axboe
  3 siblings, 0 replies; 7+ messages in thread
From: Jason A. Donenfeld @ 2022-05-20  0:40 UTC (permalink / raw)
  To: Jens Axboe, LKML; +Cc: Jason A . Donenfeld

From: Jens Axboe <axboe@kernel.dk>

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, and minimize control flow of
 write_pool().]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/char/random.c | 68 +++++++++++++++++++++++--------------------
 1 file changed, 36 insertions(+), 32 deletions(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 2b2c3681f172..a664e2b89ae0 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1278,39 +1278,32 @@ 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 *from)
 {
-	size_t block_len;
-	int ret = 0;
 	u8 block[BLAKE2S_BLOCK_SIZE];
+	ssize_t ret = 0;
 
-	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 (!iov_iter_count(from))
+		return 0;
+
+	for (;;) {
+		size_t copied, block_len = min(iov_iter_count(from), sizeof(block));
+
+		copied = copy_from_iter(block, block_len, from);
+		ret += copied;
+		mix_pool_bytes(block, copied);
+		if (!iov_iter_count(from) || copied != block_len)
+			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 *from)
 {
-	int ret;
-
-	ret = write_pool(ubuf, len);
-	if (ret)
-		return ret;
-
-	return (ssize_t)len;
+	return write_pool(from);
 }
 
 static ssize_t urandom_read_iter(struct kiocb *kiocb, struct iov_iter *to)
@@ -1349,9 +1342,8 @@ static ssize_t random_read_iter(struct kiocb *kiocb, struct iov_iter *to)
 
 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:
@@ -1368,20 +1360,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;
+
+		iov.iov_base = p;
+		iov.iov_len = len;
+		iov_iter_init(&iter, WRITE, &iov, 1, len);
+		ret = write_pool(&iter);
+		if (ret < 0)
+			return ret;
+		if (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. */
@@ -1407,7 +1411,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,
@@ -1417,7 +1421,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,
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 3/3] random: wire up fops->splice_{read,write}_iter()
  2022-05-20  0:40 [PATCH v3 0/3] random: Jens' {read,write}_iter respin Jason A. Donenfeld
  2022-05-20  0:40 ` [PATCH v3 1/3] random: convert to using fops->read_iter() Jason A. Donenfeld
  2022-05-20  0:40 ` [PATCH v3 2/3] random: convert to using fops->write_iter() Jason A. Donenfeld
@ 2022-05-20  0:40 ` Jason A. Donenfeld
  2022-05-20  1:11 ` [PATCH v3 0/3] random: Jens' {read,write}_iter respin Jens Axboe
  3 siblings, 0 replies; 7+ messages in thread
From: Jason A. Donenfeld @ 2022-05-20  0:40 UTC (permalink / raw)
  To: Jens Axboe, LKML; +Cc: Jason A . Donenfeld

From: Jens Axboe <axboe@kernel.dk>

Now that random/urandom is using {read,write}_iter, we can wire it up to
using the generic splice handlers.

Fixes: 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[Jason: added the splice_write path.]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/char/random.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index a664e2b89ae0..90d779c5d1a1 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1417,6 +1417,8 @@ const struct file_operations random_fops = {
 	.compat_ioctl = compat_ptr_ioctl,
 	.fasync = random_fasync,
 	.llseek = noop_llseek,
+	.splice_read = generic_file_splice_read,
+	.splice_write = iter_file_splice_write,
 };
 
 const struct file_operations urandom_fops = {
@@ -1426,6 +1428,8 @@ const struct file_operations urandom_fops = {
 	.compat_ioctl = compat_ptr_ioctl,
 	.fasync = random_fasync,
 	.llseek = noop_llseek,
+	.splice_read = generic_file_splice_read,
+	.splice_write = iter_file_splice_write,
 };
 
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/3] random: Jens' {read,write}_iter respin
  2022-05-20  0:40 [PATCH v3 0/3] random: Jens' {read,write}_iter respin Jason A. Donenfeld
                   ` (2 preceding siblings ...)
  2022-05-20  0:40 ` [PATCH v3 3/3] random: wire up fops->splice_{read,write}_iter() Jason A. Donenfeld
@ 2022-05-20  1:11 ` Jens Axboe
  3 siblings, 0 replies; 7+ messages in thread
From: Jens Axboe @ 2022-05-20  1:11 UTC (permalink / raw)
  To: Jason A. Donenfeld, LKML

On 5/19/22 6:40 PM, Jason A. Donenfeld wrote:
> Hey Jens,
> 
> Here's what I've done to your patches. Could you let me know if I've
> mangled anything in the process?

Looks good, just one request for patch 1, I'll send it separately.
Feel free to queue them up, thanks.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/3] random: convert to using fops->read_iter()
  2022-05-20  0:40 ` [PATCH v3 1/3] random: convert to using fops->read_iter() Jason A. Donenfeld
@ 2022-05-20  1:11   ` Jens Axboe
  2022-05-20  9:04     ` Jason A. Donenfeld
  0 siblings, 1 reply; 7+ messages in thread
From: Jens Axboe @ 2022-05-20  1:11 UTC (permalink / raw)
  To: Jason A. Donenfeld, LKML

On 5/19/22 6:40 PM, Jason A. Donenfeld wrote:
> From: Jens Axboe <axboe@kernel.dk>
> 
> This is a pre-requisite to writing up splice() again for the random
> and urandom drivers.

s/writing/wiring

Looks like I typo'ed that one.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/3] random: convert to using fops->read_iter()
  2022-05-20  1:11   ` Jens Axboe
@ 2022-05-20  9:04     ` Jason A. Donenfeld
  0 siblings, 0 replies; 7+ messages in thread
From: Jason A. Donenfeld @ 2022-05-20  9:04 UTC (permalink / raw)
  To: Jens Axboe; +Cc: LKML

On Thu, May 19, 2022 at 07:11:37PM -0600, Jens Axboe wrote:
> On 5/19/22 6:40 PM, Jason A. Donenfeld wrote:
> > From: Jens Axboe <axboe@kernel.dk>
> > 
> > This is a pre-requisite to writing up splice() again for the random
> > and urandom drivers.
> 
> s/writing/wiring
> 
> Looks like I typo'ed that one.

Will fix.

Jason

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-05-20  9:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-20  0:40 [PATCH v3 0/3] random: Jens' {read,write}_iter respin Jason A. Donenfeld
2022-05-20  0:40 ` [PATCH v3 1/3] random: convert to using fops->read_iter() Jason A. Donenfeld
2022-05-20  1:11   ` Jens Axboe
2022-05-20  9:04     ` Jason A. Donenfeld
2022-05-20  0:40 ` [PATCH v3 2/3] random: convert to using fops->write_iter() Jason A. Donenfeld
2022-05-20  0:40 ` [PATCH v3 3/3] random: wire up fops->splice_{read,write}_iter() Jason A. Donenfeld
2022-05-20  1:11 ` [PATCH v3 0/3] random: Jens' {read,write}_iter respin Jens Axboe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.