• Jason A. Donenfeld's avatar
    random: block in /dev/urandom · 6f98a4bf
    Jason A. Donenfeld authored
    This topic has come up countless times, and usually doesn't go anywhere.
    This time I thought I'd bring it up with a slightly narrower focus,
    updated for some developments over the last three years: we finally can
    make /dev/urandom always secure, in light of the fact that our RNG is
    now always seeded.
    
    Ever since Linus' 50ee7529 ("random: try to actively add entropy
    rather than passively wait for it"), the RNG does a haveged-style jitter
    dance around the scheduler, in order to produce entropy (and credit it)
    for the case when we're stuck in wait_for_random_bytes(). How ever you
    feel about the Linus Jitter Dance is beside the point: it's been there
    for three years and usually gets the RNG initialized in a second or so.
    
    As a matter of fact, this is what happens currently when people use
    getrandom(). It's already there and working, and most people have been
    using it for years without realizing.
    
    So, given that the kernel has grown this mechanism for seeding itself
    from nothing, and that this procedure happens pretty fast, maybe there's
    no point any longer in having /dev/urandom give insecure bytes. In the
    past we didn't want the boot process to deadlock, which was
    understandable. But now, in the worst case, a second goes by, and the
    problem is resolved. It seems like maybe we're finally at a point when
    we can get rid of the infamous "urandom read hole".
    
    The one slight drawback is that the Linus Jitter Dance relies on random_
    get_entropy() being implemented. The first lines of try_to_generate_
    entropy() are:
    
    	stack.now = random_get_entropy();
    	if (stack.now == random_get_entropy())
    		return;
    
    On most platforms, random_get_entropy() is simply aliased to get_cycles().
    The number of machines without a cycle counter or some other
    implementation of random_get_entropy() in 2022, which can also run a
    mainline kernel, and at the same time have a both broken and out of date
    userspace that relies on /dev/urandom never blocking at boot is thought
    to be exceedingly low. And to be clear: those museum pieces without
    cycle counters will continue to run Linux just fine, and even
    /dev/urandom will be operable just like before; the RNG just needs to be
    seeded first through the usual means, which should already be the case
    now.
    
    On systems that really do want unseeded randomness, we already offer
    getrandom(GRND_INSECURE), which is in use by, e.g., systemd for seeding
    their hash tables at boot. Nothing in this commit would affect
    GRND_INSECURE, and it remains the means of getting those types of random
    numbers.
    
    This patch goes a long way toward eliminating a long overdue userspace
    crypto footgun. After several decades of endless user confusion, we will
    finally be able to say, "use any single one of our random interfaces and
    you'll be fine. They're all the same. It doesn't matter." And that, I
    think, is really something. Finally all of those blog posts and
    disagreeing forums and contradictory articles will all become correct
    about whatever they happened to recommend, and along with it, a whole
    class of vulnerabilities eliminated.
    
    With very minimal downside, we're finally in a position where we can
    make this change.
    
    Cc: Dinh Nguyen <dinguyen@kernel.org>
    Cc: Nick Hu <nickhu@andestech.com>
    Cc: Max Filippov <jcmvbkbc@gmail.com>
    Cc: Palmer Dabbelt <palmer@dabbelt.com>
    Cc: David S. Miller <davem@davemloft.net>
    Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
    Cc: Michal Simek <monstr@monstr.eu>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Guo Ren <guoren@kernel.org>
    Cc: Geert Uytterhoeven <geert@linux-m68k.org>
    Cc: Joshua Kinard <kumba@gentoo.org>
    Cc: David Laight <David.Laight@aculab.com>
    Cc: Dominik Brodowski <linux@dominikbrodowski.net>
    Cc: Eric Biggers <ebiggers@google.com>
    Cc: Ard Biesheuvel <ardb@kernel.org>
    Cc: Arnd Bergmann <arnd@arndb.de>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Andy Lutomirski <luto@kernel.org>
    Cc: Kees Cook <keescook@chromium.org>
    Cc: Lennart Poettering <mzxreary@0pointer.de>
    Cc: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Theodore Ts'o <tytso@mit.edu>
    Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
    6f98a4bf
random.c 47 KB