linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
To: linux-kernel@vger.kernel.org, linux@dominikbrodowski.net
Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>, Theodore Ts'o <tytso@mit.edu>
Subject: [PATCH v2 08/10] random: group userspace read/write functions
Date: Sat, 12 Feb 2022 13:23:16 +0100	[thread overview]
Message-ID: <20220212122318.623435-9-Jason@zx2c4.com> (raw)
In-Reply-To: <20220212122318.623435-1-Jason@zx2c4.com>

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>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/char/random.c | 125 ++++++++++++++++++++++++++----------------
 1 file changed, 77 insertions(+), 48 deletions(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index d878c8506af9..b2af2dc96d20 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1462,30 +1462,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)
+
+/**********************************************************************
+ *
+ * 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)
 {
-	static int maxwarn = 10;
+	if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
+		return -EINVAL;
 
-	if (!crng_ready() && maxwarn > 0) {
-		maxwarn--;
-		if (__ratelimit(&urandom_warning))
-			pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
-				  current->comm, nbytes);
-	}
+	/*
+	 * Requesting insecure and blocking randomness at the same time makes
+	 * no sense.
+	 */
+	if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
+		return -EINVAL;
 
-	return get_random_bytes_user(buf, nbytes);
-}
+	if (count > INT_MAX)
+		count = INT_MAX;
 
-static ssize_t random_read(struct file *file, char __user *buf, size_t nbytes,
-			   loff_t *ppos)
-{
-	int ret;
+	if (!(flags & GRND_INSECURE) && !crng_ready()) {
+		int ret;
 
-	ret = wait_for_random_bytes();
-	if (ret != 0)
-		return ret;
-	return get_random_bytes_user(buf, nbytes);
+		if (flags & GRND_NONBLOCK)
+			return -EAGAIN;
+		ret = wait_for_random_bytes();
+		if (unlikely(ret))
+			return ret;
+	}
+	return get_random_bytes_user(buf, count);
 }
 
 static __poll_t random_poll(struct file *file, poll_table *wait)
@@ -1537,6 +1568,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;
@@ -1545,7 +1602,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;
@@ -1621,34 +1678,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
-- 
2.35.0


  parent reply	other threads:[~2022-02-12 12:24 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-12 12:23 [PATCH v2 00/10] random: re-group and re-document functions Jason A. Donenfeld
2022-02-12 12:23 ` [PATCH v2 01/10] random: introduce drain_entropy() helper to declutter crng_reseed() Jason A. Donenfeld
2022-02-21  4:34   ` Eric Biggers
2022-02-21 14:49     ` Jason A. Donenfeld
2022-02-21 14:49       ` [PATCH v3] " Jason A. Donenfeld
2022-02-21 19:19         ` Eric Biggers
2022-02-12 12:23 ` [PATCH v2 02/10] random: remove useless header comment Jason A. Donenfeld
2022-02-21  4:34   ` Eric Biggers
2022-02-12 12:23 ` [PATCH v2 03/10] random: remove whitespace and reorder includes Jason A. Donenfeld
2022-02-21  4:35   ` Eric Biggers
2022-02-12 12:23 ` [PATCH v2 04/10] random: group initialization wait functions Jason A. Donenfeld
2022-02-13  6:54   ` Dominik Brodowski
2022-02-13 13:11     ` Jason A. Donenfeld
2022-02-21  4:49   ` Eric Biggers
2022-02-21 15:10     ` Jason A. Donenfeld
2022-02-21 15:14       ` [PATCH v3] " Jason A. Donenfeld
2022-02-21 19:20         ` Eric Biggers
2022-02-12 12:23 ` [PATCH v2 05/10] random: group crng functions Jason A. Donenfeld
2022-02-13  6:54   ` Dominik Brodowski
2022-02-13 13:14     ` Jason A. Donenfeld
2022-02-21  5:00   ` Eric Biggers
2022-02-12 12:23 ` [PATCH v2 06/10] random: group entropy extraction functions Jason A. Donenfeld
2022-02-21  5:05   ` Eric Biggers
2022-02-12 12:23 ` [PATCH v2 07/10] random: group entropy collection functions Jason A. Donenfeld
2022-02-13  6:54   ` Dominik Brodowski
2022-02-13 13:16     ` Jason A. Donenfeld
2022-02-21  5:13   ` Eric Biggers
2022-02-21 15:17     ` Jason A. Donenfeld
2022-02-21 15:18       ` [PATCH v3] " Jason A. Donenfeld
2022-02-21 19:23         ` Eric Biggers
2022-02-12 12:23 ` Jason A. Donenfeld [this message]
2022-02-21  5:16   ` [PATCH v2 08/10] random: group userspace read/write functions Eric Biggers
2022-02-12 12:23 ` [PATCH v2 09/10] random: group sysctl functions Jason A. Donenfeld
2022-02-21  5:21   ` Eric Biggers
2022-02-21 15:27     ` Jason A. Donenfeld
2022-02-21 15:39       ` Jason A. Donenfeld
2022-02-12 12:23 ` [PATCH v2 10/10] random: rewrite header introductory comment Jason A. Donenfeld
2022-02-21  5:26   ` Eric Biggers
2022-02-13  6:55 ` [PATCH v2 00/10] random: re-group and re-document functions Dominik Brodowski
2022-02-13 13:07   ` Jason A. Donenfeld

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220212122318.623435-9-Jason@zx2c4.com \
    --to=jason@zx2c4.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@dominikbrodowski.net \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).