aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2022-02-07 17:19:24 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2022-11-01 20:07:17 +0100
commit8e2af1e04151cf04e7f28fc9e28b7dc1aca08e58 (patch)
tree95b6dd5f163a3b553ead27640288d893244b7119
parent2dd1a8f542ea999b249b8a85ece57553289a2b6d (diff)
downloadrandom-jd/block-urandom.tar.gz
random: block in /dev/urandomjd/block-urandom
The last time this was attempted, in 6f98a4bfee72 ("random: block in /dev/urandom"), we had to revert, because the Linus Jitter Dance didn't work on a few platforms that were actively getting new kernels with broken userspaces. This has now changed, on several fronts: - Platforms without cycle counters now fall back to the highest resolution clock that the platform has to offer. - The jitter algorithm now attempts to take more samples on platforms with slower counters, measuring dynamically at runtime. - Many userspaces have now been fixed (by way of my SeedRNG project), which doesn't account for old userspaces of course, but the odd architectures that are getting new userspaces and new kernels (which seems to mostly be QEMU test harnesses) now won't even need jitter entropy at all. The first two reasons make this attempt a much more sure bet than the last one -- since broken userspaces now shouldn't be impacted by it -- while the last reason is just a general positive ecosystem improvement. Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--drivers/char/mem.c2
-rw-r--r--drivers/char/random.c72
-rw-r--r--include/linux/random.h2
3 files changed, 13 insertions, 63 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 5611d127363e47..3f6d0a26adb99e 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -713,7 +713,7 @@ static const struct memdev {
[5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT },
[7] = { "full", 0666, &full_fops, 0 },
[8] = { "random", 0666, &random_fops, FMODE_NOWAIT },
- [9] = { "urandom", 0666, &urandom_fops, FMODE_NOWAIT },
+ [9] = { "urandom", 0666, &random_fops, FMODE_NOWAIT },
#ifdef CONFIG_PRINTK
[11] = { "kmsg", 0644, &kmsg_fops, 0 },
#endif
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 5da120f10a67a4..1d3b34f529da9e 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -85,19 +85,11 @@ static DEFINE_STATIC_KEY_FALSE(crng_is_ready);
static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
static struct fasync_struct *fasync;
-/* Control how we warn userspace. */
-static struct ratelimit_state urandom_warning =
- RATELIMIT_STATE_INIT_FLAGS("urandom_warning", HZ, 3, RATELIMIT_MSG_ON_RELEASE);
-static int ratelimit_disable __read_mostly =
- IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM);
-module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
-MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
-
/*
* Returns whether or not the input pool has been seeded and thus guaranteed
* to supply cryptographically secure random numbers. This applies to: the
- * /dev/urandom device, the get_random_bytes function, and the get_random_{u8,
- * u16,u32,u64,long} family of functions.
+ * get_random_bytes function and the get_random_{u8,u16,u32,u64,long} family
+ * of functions.
*
* Returns: true if the input pool has been seeded.
* false if the input pool has not been seeded.
@@ -118,9 +110,9 @@ static void try_to_generate_entropy(void);
/*
* Wait for the input pool to be seeded and thus guaranteed to supply
- * cryptographically secure random numbers. This applies to: the /dev/urandom
- * device, the get_random_bytes function, and the get_random_{u8,u16,u32,u64,
- * int,long} family of functions. Using any of these functions without first
+ * cryptographically secure random numbers. This applies to: the
+ * get_random_bytes function, and the get_random_{u8,u16,u32,u64,long}
+ * family of functions. Using any of these functions without first
* calling this function forfeits the guarantee of security.
*
* Returns: 0 if the input pool has been seeded.
@@ -688,9 +680,6 @@ static void __cold _credit_init_bits(size_t bits)
wake_up_interruptible(&crng_init_wait);
kill_fasync(&fasync, SIGIO, POLL_IN);
pr_notice("crng init done\n");
- if (urandom_warning.missed)
- pr_notice("%d urandom warning(s) missed due to ratelimiting\n",
- urandom_warning.missed);
} else if (orig < POOL_EARLY_BITS && new >= POOL_EARLY_BITS) {
spin_lock_irqsave(&base_crng.lock, flags);
/* Check if crng_init is CRNG_EMPTY, to avoid race with crng_reseed(). */
@@ -1268,20 +1257,16 @@ static void __cold 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 have the same effect
+ * as calling getrandom(2) with flags=0. (In earlier versions, however,
+ * they each had different semantics.)
*
* 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
@@ -1358,30 +1343,6 @@ static ssize_t random_write_iter(struct kiocb *kiocb, struct iov_iter *iter)
return write_pool_user(iter);
}
-static ssize_t urandom_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
-{
- static int maxwarn = 10;
-
- /*
- * Opportunistically attempt to initialize the RNG on platforms that
- * have fast cycle counters, but don't (for now) require it to succeed.
- */
- if (!crng_ready())
- try_to_generate_entropy();
-
- if (!crng_ready()) {
- if (!ratelimit_disable && maxwarn <= 0)
- ++urandom_warning.missed;
- else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
- --maxwarn;
- pr_notice("%s: uninitialized urandom read (%zu bytes read)\n",
- current->comm, iov_iter_count(iter));
- }
- }
-
- return get_random_bytes_user(iter);
-}
-
static ssize_t random_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
{
int ret;
@@ -1478,17 +1439,6 @@ const struct file_operations random_fops = {
.splice_write = iter_file_splice_write,
};
-const struct file_operations urandom_fops = {
- .read_iter = urandom_read_iter,
- .write_iter = random_write_iter,
- .unlocked_ioctl = random_ioctl,
- .compat_ioctl = compat_ptr_ioctl,
- .fasync = random_fasync,
- .llseek = noop_llseek,
- .splice_read = generic_file_splice_read,
- .splice_write = iter_file_splice_write,
-};
-
/********************************************************************
*
diff --git a/include/linux/random.h b/include/linux/random.h
index 2bdd3add340029..88910ee8984419 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -159,7 +159,7 @@ int random_online_cpu(unsigned int cpu);
#endif
#ifndef MODULE
-extern const struct file_operations random_fops, urandom_fops;
+extern const struct file_operations random_fops;
#endif
#endif /* _LINUX_RANDOM_H */