Re: Linux 5.3-rc8

From: Linus Torvalds
Date: Mon Sep 16 2019 - 01:02:43 EST


On Sun, Sep 15, 2019 at 9:30 PM Willy Tarreau <w@xxxxxx> wrote:
>
> I'd be in favor of adding in the man page something like "this
> random source is only suitable for applications which will not be
> harmed by getting a predictable value on output, and as such it is
> not suitable for generation of system keys or passwords, please
> use GRND_RANDOM for this".

The problem with GRND_RANDOM is that it also ends up extracting
entropy, and has absolutely horrendous performance behavior. It's why
hardly anybody uses /dev/random.

Which nobody should really ever do. I don't understand why people want
that thing, considering that the second law of thermodynamics really
pretty much applies. If you can crack the cryptographic hashes well
enough to break them despite reseeding etc, people will have much more
serious issues than the entropy accounting.

So the problem with getrandom() is that it only offered two flags, and
to make things worse they were the wrong ones.

Nobody should basically _ever_ use the silly "entropy can go away"
model, yet that is exactly what GRND_RANDOM does.

End result: GRND_RANDOM is almost entirely useless, and is actively
dangerous, because it can actually block not just during boot, it can
block (and cause others to block) during random running of the system
because it does that entropy accounting().

Nobody can use GRND_RANDOM if they have _any_ performance requirements
what-so-ever. It's possibly useful for one-time ssh host keys etc.

So GRND_RANDOM is just bad - with or without GRND_NONBLOCK, because
even in the nonblocking form it will account for entropy in the
blocking pool (until it's all gone, and it will return -EAGAIN).

And the non-GRND_RANDOM case avoids that problem, but requires the
initial entropy with no way to opt out of it. Yes, GRND_NONBLOCK makes
it work.

So we have four flag combinations:

- 0 - don't use if it could possibly run at boot

Possibly useful for the systemd-random-seed case, and if you *know*
you're way past boot, but clearly overused.

This is the one that bit us this time.

- GRND_NONBLOCK - fine, but you now don't get even untrusted random
numbers, and you have to come up with a way to fill the entropy pool

This one is most useful as a quick "get me urandom", but needs a
fallback to _actual_ /dev/urandom when it fails.

This is the best choice by far, and has no inherent downsides apart
from needing that fallback code.

- GRND_RANDOM - don't use

This will block and it will decrease the blocking pool entropy so
that others will block too, and has horrible performance.

Just don't use it outside of very occasional non-serious work.

Yes, it will give you secure numbers, but because of performance
issues it's not viable for any serious code, and obviously not for
bootup.

It can be useful as a seed for future serious use that just does
all random handling in user space. Just not during boot.

- GRND_RANDOM | GRND_NONBLOCK - don't use

This won't block, but it will decrease the blocking pool entropy.

It might be an acceptable "get me a truly secure ring with reliable
performance", but when it fails, you're going to be unhappy, and there
is no obvious fallback.

So three out of four flag combinations end up being mostly "don't
use", and the fourth one isn't what you'd normally want (which is just
plain /dev/urandom semantics).

Linus