This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Add getrandom implementation [BZ #17252]


On 06/10/2016 11:30 PM, Joseph Myers wrote:

Are we sure we want to keep file descriptors open that the application
can't use?  Is it not valid for applications to close all open file
descriptors, or do you think that's only valid on startup before these
functions have been called?

I assumed closing file descriptors is only valid right before an execve. But I see that historically, we have avoid really hard to keep open file descriptors not explicitly requested by the application. The socket for communicating with nscd is one such example. We also do not keep open Netlink sockets to receive kernel notifications about configuration changes (which would allow us to skip costly interface enumeration, at least in theory if the notifications were reliable).

Clearly, we have a requirement that the application doesn't go beyond the back of the library and unmaps memory regions. I assumed a similar rule existed for file descriptors. A lot of other libraries use file descriptors internally as well, so this is certainly a de-facto requirement for most applications. But it may be the case that glibc itself cannot rely on this.

Keeping open the file descriptors is not just a performance optimization. It may be necessary for supporting getrandom after a chroot call, and one explicitly stated goal of adding the system call was preventing file descriptor starvation attacks. We also had an implementation of OpenSSL's RAND_bytes function which did not return the correct success/failure flags, and that wasn't noticed by anyone. Apparently, programmers do not check for error returns from random number generators. Based on that, I concluded it was important to provide an implementation which cannot fail.

On the other hand, application developers are not expected to call getrandom (or getentropy) directly. In our implementation, this depletes the overall entropy pool, and it is also rather slow. The OpenBSD interface intended for application use is called arc4random (for historical reasons). Implementing arc4random has both libc aspects (providing thread safety and invalidating the internal state around clone/fork) and cryptographic aspects (for performance reasons, it has to be a deterministic random bit generator, and use the kernel for seeding only). I think the cryptographic aspect dominates, which is why it is difficult to implement arc4random as part of glibc.

So a completely different approach would be to provide a thin wrapper around getrandom, not its limitations, and tell applications to use a cryptographic library if they need a stream of randomness.

But then, we have lots of of libraries which need 32 or 64 bits to initialize a keyed hash function to avoid hash collision denial of service attacks. (The key is set just once and shared across hash tables.) For this purpose, it is acceptable to call getrandom and get the bits from the kernel, and it makes sense for glibc to provide emulation so that the function is always available, simply we cannot provide arc4random.

Thank you for your other comments, they are helpful.

Florian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]