> On Sep 20, 2019, at 11:10 AM, Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote: > > On Fri, Sep 20, 2019 at 10:52 AM Andy Lutomirski <luto@xxxxxxxxxx> wrote: >> >> IMO, from the beginning, we should have done this: >> >> GRND_INSECURE: insecure. always works. >> >> GRND_SECURE_BLOCKING: does exactly what it says. >> >> 0: -EINVAL. > > Violently agreed. And that's kind of what the GRND_EXPLICIT is really > aiming for. > > However, it's worth noting that nobody should ever use GRND_EXPLICIT > directly. That's just the name for the bit. The actual users would use > GRND_INSECURE or GRND_SECURE. > > And yes, maybe it's worth making the name be GRND_SECURE_BLOCKING just > to make people see what the big deal is. > > In the meantime, we need that new bit just to be able to create the > new semantics eventually. With a warning to nudge people in the right > direction. > > We may never be able to return -EINVAL, but we can add the pr_notice() > to discourage people from using it. > The problem is that new programs will have to try the new flag value and, if it returns -EINVAL, fall back to 0. This isn't so great. > And yes, we'll have to block - at least for a time - to get some > entropy. But at some point we either start making entropy up, or we > say "0 means jitter-entropy for ten seconds". > > That will _work_, but it will also make the security-people nervous, > which is just one more hint that they should move to > GRND_SECURE[_BLOCKING]. Wait, are you suggesting that 0 means invoke jitter-entropy or whatever and GRND_SECURE_BLOCKING means not wait forever and deadlock? That's no good -- people will want to continue using 0 because the behavior is better. My point here is that asking for secure random numbers isn’t some legacy oddity — it’s genuinely necessary. The kernel should do whatever it needs to in order to make it work. We really don’t want a situation where 0 means get me secure random numbers reliably but spam the logs and GRND_SECURE_BLOCKING means don’t spam the logs but risk deadlocking. This will encourage people to pass 0 to get the improved behavior. > So GRND_EXPLICIT is a bit that basically means "I am explicit about > what behavior I want". But part of that is that you need to _state_ > the behavior too. > > So: > > - GRND_INSECURE is (GRND_EXPLICIT | GRND_NONBLOCK) > > As in "I explicitly ask you not to just not ever block": urandom IMO this is confusing. The GRND_RANDOM flag was IMO a mistake and should just be retired. Let's enumerate useful cases and then give them sane values. > > - GRND_SECURE_BLOCKING is (GRND_EXPLICIT | GRND_RANDOM) > > As in "I explicitly ask you for those secure random numbers" > > - GRND_SECURE_NONBLOCKING is (GRND_EXPLICIT | GRND_RANDOM | GRND_NONBLOCK) > > As in "I want explicitly secure random numbers, but return -EAGAIN > if that would block". > > Which are the three sane behaviors (that last one is useful for the "I > can try to generate entropy if you don't have any" case. I'm not sure > anybody will do it, but it definitely conceptually makes sense). > > And I agree that your naming is better. I think this is the complete list of "good" behaviors for new programs: "insecure": always works, never warns. "secure, blocking": always returns *eventually* with secure output, i.e., does something to avoid deadlocks "secure, nonblocking" returns secure output immediately or returns -EAGAIN. And the only real question is how to map existing users to these semantics. I see two sensible choices: 1. 0 means "secure, blocking". I think this is not what we'd do if we could go back in time and chage the ABI from day 1, but I think it's actually good enough. As long as this mode won't deadlock, it's not *that* bad if programs are using it when they wanted "insecure". 2. 0 means "secure, blocking, but warn". Some new value means "secure, blocking, don't warn". The problem is that new applications will have to fall back to 0 to continue supporting old kernels. I briefly thought that maybe GRND_RANDOM would be a reasonable choice for "secure, blocking, don't warn", but the effect on new programs on old kernels will be unfortunate. I'm willing to go along with #2 if you like it better than #1, and I'll update my patches accordingly, but I prefer #1. I do think we should make all the ABI changes that we want to make all in one release. Let's not make programs think about their behavior on more versions than necessary. So I'd like to get rid of the current /dev/random semantics, add "insecure" mode, and do whatever deadlock avoidance scheme we settle on in a single release. --Andy