mirror of https://lore.kernel.org/lkml/
 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	[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	[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	[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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®