Re: Linux 5.3-rc8

From: Ahmed S. Darwish
Date: Sat Sep 14 2019 - 11:04:33 EST


On Thu, Sep 12, 2019 at 12:34:45PM +0100, Linus Torvalds wrote:
> On Thu, Sep 12, 2019 at 9:25 AM Theodore Y. Ts'o <tytso@xxxxxxx> wrote:
> >
> > Hmm, one thought might be GRND_FAILSAFE, which will wait up to two
> > minutes before returning "best efforts" randomness and issuing a huge
> > massive warning if it is triggered?
>
> Yeah, based on (by now) _years_ of experience with people mis-using
> "get me random numbers", I think the sense of a new flag needs to be
> "yeah, I'm willing to wait for it".
>
> Because most people just don't want to wait for it, and most people
> don't think about it, and we need to make the default be for that
> "don't think about it" crowd, with the people who ask for randomness
> sources for a secure key having to very clearly and very explicitly
> say "Yes, I understand that this can take minutes and can only be done
> long after boot".
>
> Even then people will screw that up because they copy code, or some
> less than gifted rodent writes a library and decides "my library is so
> important that I need that waiting sooper-sekrit-secure random
> number", and then people use that broken library by mistake without
> realizing that it's not going to be reliable at boot time.
>
> An alternative might be to make getrandom() just return an error
> instead of waiting. Sure, fill the buffer with "as random as we can"
> stuff, but then return -EINVAL because you called us too early.
>

ACK, that's probably _the_ most sensible approach. Only caveat is
the slight change in user-space API semantics though...

For example, this breaks the just released systemd-random-seed(8)
as it _explicitly_ requests blocking behvior from getrandom() here:

=> src/random-seed/random-seed.c:
/*
* Let's make this whole job asynchronous, i.e. let's make
* ourselves a barrier for proper initialization of the
* random pool.
*/
k = getrandom(buf, buf_size, GRND_NONBLOCK);
if (k < 0 && errno == EAGAIN && synchronous) {
log_notice("Kernel entropy pool is not initialized yet, "
"waiting until it is.");

k = getrandom(buf, buf_size, 0); /* retry synchronously */
}
if (k < 0) {
log_debug_errno(errno, "Failed to read random data with "
"getrandom(), falling back to "
"/dev/urandom: %m");
} else if ((size_t) k < buf_size) {
log_debug("Short read from getrandom(), falling back to "
"/dev/urandom: %m");
} else {
getrandom_worked = true;
}

Nonetheless, a slightly broken systemd-random-seed, that was just
released only 11 days ago (v243), is honestly much better than a
*non-booting system*...

I've sent an RFC patch at [1].

To handle the systemd case, I'll add the discussed "yeah, I'm
willing to wait for it" flag (GRND_BLOCK) in v2.

If this whole approach is going to be merged, and the slight ABI
breakage is to be tolerated (hmmmmm?), I wonder how will systemd
random-seed handle the semantics change though without doing
ugly kernel version checks..

thanks,

[1] 20190914122500.GA1425@darwi-home-pc">https://lkml.kernel.org/r/20190914122500.GA1425@darwi-home-pc

--
darwi
http://darwish.chasingpointers.com