[PATCH] Add getrandom implementation [BZ #17252]

Florian Weimer fweimer@redhat.com
Sat Jun 11 11:13:00 GMT 2016


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



More information about the Libc-alpha mailing list