mirror of
https://gitlab.freedesktop.org/libbsd/libbsd.git
synced 2025-10-21 15:51:46 +02:00
Update getentropy() code from OpenBSD
Includes changes to handle the Linux syscall blocking when there is not enough entropy during boot, by switching it to non-blocking mode and falling back to the alternative implementations. Man page URL reference fixes. Build fixes for Mac OS X. Fixes: https://bugs.debian.org/898088
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: getentropy_linux.c,v 1.40 2015/08/25 17:26:43 deraadt Exp $ */
|
||||
/* $OpenBSD: getentropy_linux.c,v 1.45 2018/03/13 22:53:28 bcook Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
@@ -17,7 +17,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Emulation of getentropy(2) as documented at:
|
||||
* http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
@@ -75,7 +75,7 @@
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
static int gotdata(char *buf, size_t len);
|
||||
#ifdef SYS_getrandom
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
static int getentropy_getrandom(void *buf, size_t len);
|
||||
#endif
|
||||
static int getentropy_urandom(void *buf, size_t len);
|
||||
@@ -95,15 +95,18 @@ getentropy(void *buf, size_t len)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifdef SYS_getrandom
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
/*
|
||||
* Try descriptor-less getrandom()
|
||||
* Try descriptor-less getrandom(), in non-blocking mode.
|
||||
*
|
||||
* The design of Linux getrandom is broken. It has an
|
||||
* uninitialized phase coupled with blocking behaviour, which
|
||||
* is unacceptable from within a library at boot time without
|
||||
* possible recovery. See http://bugs.python.org/issue26839#msg267745
|
||||
*/
|
||||
ret = getentropy_getrandom(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
if (errno != ENOSYS)
|
||||
return (-1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -121,7 +124,7 @@ getentropy(void *buf, size_t len)
|
||||
* Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
|
||||
* sysctl is a failsafe API, so it guarantees a result. This
|
||||
* should work inside a chroot, or when file descriptors are
|
||||
* exhuasted.
|
||||
* exhausted.
|
||||
*
|
||||
* However this can fail if the Linux kernel removes support
|
||||
* for sysctl. Starting in 2007, there have been efforts to
|
||||
@@ -157,7 +160,7 @@ getentropy(void *buf, size_t len)
|
||||
* - Do the best under the circumstances....
|
||||
*
|
||||
* This code path exists to bring light to the issue that Linux
|
||||
* does not provide a failsafe API for entropy collection.
|
||||
* still does not provide a failsafe API for entropy collection.
|
||||
*
|
||||
* We hope this demonstrates that Linux should either retain their
|
||||
* sysctl ABI, or consider providing a new failsafe API which
|
||||
@@ -191,7 +194,7 @@ gotdata(char *buf, size_t len)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef SYS_getrandom
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
static int
|
||||
getentropy_getrandom(void *buf, size_t len)
|
||||
{
|
||||
@@ -200,7 +203,7 @@ getentropy_getrandom(void *buf, size_t len)
|
||||
if (len > 256)
|
||||
return (-1);
|
||||
do {
|
||||
ret = syscall(SYS_getrandom, buf, len, 0);
|
||||
ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
if (ret != (int)len)
|
||||
|
Reference in New Issue
Block a user