From: "Jason A. Donenfeld" <Jason@zx2c4.com>
To: Lennart Poettering <mzxreary@0pointer.de>
Cc: linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
linux-riscv@lists.infradead.org,
Geert Uytterhoeven <geert@linux-m68k.org>,
linux-m68k@lists.linux-m68k.org,
Thomas Bogendoerfer <tsbogend@alpha.franken.de>,
linux-mips@vger.kernel.org,
Dominik Brodowski <linux@dominikbrodowski.net>,
Eric Biggers <ebiggers@google.com>,
Ard Biesheuvel <ardb@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Thomas Gleixner <tglx@linutronix.de>,
Andy Lutomirski <luto@kernel.org>,
Kees Cook <keescook@chromium.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Theodore Ts'o <tytso@mit.edu>
Subject: Re: [PATCH RFC v0] random: block in /dev/urandom
Date: Mon, 14 Feb 2022 15:13:18 +0100 [thread overview]
Message-ID: <YgpjfncV+C9FEZDc@zx2c4.com> (raw)
In-Reply-To: <YgoYnX97imub7KEB@gardel-login>
Hi Lennart,
On Mon, Feb 14, 2022 at 9:53 AM Lennart Poettering <mzxreary@0pointer.de> wrote:
> So, systemd uses (potentially half-initialized) /dev/urandom for
> seeding its hash tables. For that its kinda OK if the random values
> have low entropy initially, as we'll automatically reseed when too
> many hash collisions happen, and then use a newer (and thus hopefully
> better) seed, again acquired through /dev/urandom. i.e. if the seeds
> are initially not good enough to thwart hash collision attacks, once
> the hash table are actually attacked we'll replace the seeds with
> someting better. For that all we need is that the random pool
> eventually gets better, that's all.
>
> So for that usecase /dev/urandom behaving the way it so far does is
> kinda nice.
Oh that's an interesting point. But that sounds to me like the problem
with this patch is not that it makes /dev/urandom block (its primary
purpose) but that it also removes GRND_INSECURE (a distraction). So
perhaps an improved patch would be something like the below, which
changes /dev/urandom for new kernels but doesn't remove GRND_INSECURE.
Then your hash tables could continue to use GRND_INSECURE and all would
be well. (And for kernels without getrandom(), they'd just fall back to
/dev/urandom like normal which would have old semantics, so works.)
Jason
---------8<-----------------8<-------------------------------
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index cc296f0823bd..9f586025dbe6 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -707,7 +707,7 @@ static const struct memdev {
[5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT },
[7] = { "full", 0666, &full_fops, 0 },
[8] = { "random", 0666, &random_fops, 0 },
- [9] = { "urandom", 0666, &urandom_fops, 0 },
+ [9] = { "urandom", 0666, &random_fops, 0 },
#ifdef CONFIG_PRINTK
[11] = { "kmsg", 0644, &kmsg_fops, 0 },
#endif
diff --git a/drivers/char/random.c b/drivers/char/random.c
index ce199af9bc56..ae4400c48b2f 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -89,8 +89,6 @@ static LIST_HEAD(random_ready_list);
/* Control how we warn userspace. */
static struct ratelimit_state unseeded_warning =
RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3);
-static struct ratelimit_state urandom_warning =
- RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3);
static int ratelimit_disable __read_mostly;
module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
@@ -336,11 +334,6 @@ static void crng_reseed(void)
unseeded_warning.missed);
unseeded_warning.missed = 0;
}
- if (urandom_warning.missed) {
- pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
- urandom_warning.missed);
- urandom_warning.missed = 0;
- }
}
}
@@ -993,10 +986,8 @@ int __init rand_initialize(void)
pr_notice("crng init done (trusting CPU's manufacturer)\n");
}
- if (ratelimit_disable) {
- urandom_warning.interval = 0;
+ if (ratelimit_disable)
unseeded_warning.interval = 0;
- }
return 0;
}
@@ -1387,20 +1378,17 @@ static void try_to_generate_entropy(void)
* 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.
+ * Reading from /dev/random and /dev/urandom both the same effect as
+ * calling getrandom(2) with flags=0. In earlier versions, however,
+ * they each had vastly different semantics and should therefore be
+ * avoided to prevent backwards compatibility issues.
*
* 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.
+ * Polling on /dev/random or /dev/urandom 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
@@ -1485,21 +1473,6 @@ 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)
{
@@ -1586,15 +1559,6 @@ const struct file_operations random_fops = {
.llseek = noop_llseek,
};
-const struct file_operations urandom_fops = {
- .read = urandom_read,
- .write = random_write,
- .unlocked_ioctl = random_ioctl,
- .compat_ioctl = compat_ptr_ioctl,
- .fasync = random_fasync,
- .llseek = noop_llseek,
-};
-
/********************************************************************
*
WARNING: multiple messages have this Message-ID (diff)
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
To: Lennart Poettering <mzxreary@0pointer.de>
Cc: linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
linux-riscv@lists.infradead.org,
Geert Uytterhoeven <geert@linux-m68k.org>,
linux-m68k@lists.linux-m68k.org,
Thomas Bogendoerfer <tsbogend@alpha.franken.de>,
linux-mips@vger.kernel.org,
Dominik Brodowski <linux@dominikbrodowski.net>,
Eric Biggers <ebiggers@google.com>,
Ard Biesheuvel <ardb@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Thomas Gleixner <tglx@linutronix.de>,
Andy Lutomirski <luto@kernel.org>,
Kees Cook <keescook@chromium.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Theodore Ts'o <tytso@mit.edu>
Subject: Re: [PATCH RFC v0] random: block in /dev/urandom
Date: Mon, 14 Feb 2022 15:13:18 +0100 [thread overview]
Message-ID: <YgpjfncV+C9FEZDc@zx2c4.com> (raw)
In-Reply-To: <YgoYnX97imub7KEB@gardel-login>
Hi Lennart,
On Mon, Feb 14, 2022 at 9:53 AM Lennart Poettering <mzxreary@0pointer.de> wrote:
> So, systemd uses (potentially half-initialized) /dev/urandom for
> seeding its hash tables. For that its kinda OK if the random values
> have low entropy initially, as we'll automatically reseed when too
> many hash collisions happen, and then use a newer (and thus hopefully
> better) seed, again acquired through /dev/urandom. i.e. if the seeds
> are initially not good enough to thwart hash collision attacks, once
> the hash table are actually attacked we'll replace the seeds with
> someting better. For that all we need is that the random pool
> eventually gets better, that's all.
>
> So for that usecase /dev/urandom behaving the way it so far does is
> kinda nice.
Oh that's an interesting point. But that sounds to me like the problem
with this patch is not that it makes /dev/urandom block (its primary
purpose) but that it also removes GRND_INSECURE (a distraction). So
perhaps an improved patch would be something like the below, which
changes /dev/urandom for new kernels but doesn't remove GRND_INSECURE.
Then your hash tables could continue to use GRND_INSECURE and all would
be well. (And for kernels without getrandom(), they'd just fall back to
/dev/urandom like normal which would have old semantics, so works.)
Jason
---------8<-----------------8<-------------------------------
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index cc296f0823bd..9f586025dbe6 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -707,7 +707,7 @@ static const struct memdev {
[5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT },
[7] = { "full", 0666, &full_fops, 0 },
[8] = { "random", 0666, &random_fops, 0 },
- [9] = { "urandom", 0666, &urandom_fops, 0 },
+ [9] = { "urandom", 0666, &random_fops, 0 },
#ifdef CONFIG_PRINTK
[11] = { "kmsg", 0644, &kmsg_fops, 0 },
#endif
diff --git a/drivers/char/random.c b/drivers/char/random.c
index ce199af9bc56..ae4400c48b2f 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -89,8 +89,6 @@ static LIST_HEAD(random_ready_list);
/* Control how we warn userspace. */
static struct ratelimit_state unseeded_warning =
RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3);
-static struct ratelimit_state urandom_warning =
- RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3);
static int ratelimit_disable __read_mostly;
module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
@@ -336,11 +334,6 @@ static void crng_reseed(void)
unseeded_warning.missed);
unseeded_warning.missed = 0;
}
- if (urandom_warning.missed) {
- pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
- urandom_warning.missed);
- urandom_warning.missed = 0;
- }
}
}
@@ -993,10 +986,8 @@ int __init rand_initialize(void)
pr_notice("crng init done (trusting CPU's manufacturer)\n");
}
- if (ratelimit_disable) {
- urandom_warning.interval = 0;
+ if (ratelimit_disable)
unseeded_warning.interval = 0;
- }
return 0;
}
@@ -1387,20 +1378,17 @@ static void try_to_generate_entropy(void)
* 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.
+ * Reading from /dev/random and /dev/urandom both the same effect as
+ * calling getrandom(2) with flags=0. In earlier versions, however,
+ * they each had vastly different semantics and should therefore be
+ * avoided to prevent backwards compatibility issues.
*
* 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.
+ * Polling on /dev/random or /dev/urandom 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
@@ -1485,21 +1473,6 @@ 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)
{
@@ -1586,15 +1559,6 @@ const struct file_operations random_fops = {
.llseek = noop_llseek,
};
-const struct file_operations urandom_fops = {
- .read = urandom_read,
- .write = random_write,
- .unlocked_ioctl = random_ioctl,
- .compat_ioctl = compat_ptr_ioctl,
- .fasync = random_fasync,
- .llseek = noop_llseek,
-};
-
/********************************************************************
*
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2022-02-14 14:15 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-11 21:07 [PATCH RFC v0] random: block in /dev/urandom Jason A. Donenfeld
2022-02-11 21:07 ` Jason A. Donenfeld
2022-02-11 21:29 ` Linus Torvalds
2022-02-11 21:29 ` Linus Torvalds
2022-02-11 21:56 ` Jason A. Donenfeld
2022-02-11 21:56 ` Jason A. Donenfeld
2022-02-11 22:01 ` Finn Thain
2022-02-11 22:01 ` Finn Thain
2022-02-12 23:05 ` Joshua Kinard
2022-02-12 23:05 ` Joshua Kinard
2022-02-12 23:13 ` Maciej W. Rozycki
2022-02-12 23:13 ` Maciej W. Rozycki
2022-02-14 14:05 ` Jason A. Donenfeld
2022-02-14 14:05 ` Jason A. Donenfeld
2022-02-14 14:26 ` Geert Uytterhoeven
2022-02-14 14:26 ` Geert Uytterhoeven
2022-02-14 14:57 ` David Laight
2022-02-14 14:57 ` David Laight
2022-02-14 22:53 ` Finn Thain
2022-02-14 22:53 ` Finn Thain
2022-03-01 19:27 ` 10maurycy10
2022-02-13 3:15 ` Andy Lutomirski
2022-02-13 3:15 ` Andy Lutomirski
2022-02-14 8:53 ` Lennart Poettering
2022-02-14 8:53 ` Lennart Poettering
2022-02-14 14:13 ` Jason A. Donenfeld [this message]
2022-02-14 14:13 ` Jason A. Donenfeld
2022-02-14 14:53 ` Lennart Poettering
2022-02-14 14:53 ` Lennart Poettering
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=YgpjfncV+C9FEZDc@zx2c4.com \
--to=jason@zx2c4.com \
--cc=aou@eecs.berkeley.edu \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=ebiggers@google.com \
--cc=geert@linux-m68k.org \
--cc=gregkh@linuxfoundation.org \
--cc=keescook@chromium.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-m68k@lists.linux-m68k.org \
--cc=linux-mips@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux@dominikbrodowski.net \
--cc=luto@kernel.org \
--cc=mzxreary@0pointer.de \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--cc=tsbogend@alpha.franken.de \
--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 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.