Merge "bionic: make NONBLOCK call to getrandom"
diff --git a/libc/bionic/bionic_arc4random.cpp b/libc/bionic/bionic_arc4random.cpp
index 429ff7f..4ff18ab 100644
--- a/libc/bionic/bionic_arc4random.cpp
+++ b/libc/bionic/bionic_arc4random.cpp
@@ -38,11 +38,12 @@
#include "private/libc_logging.h"
void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args) {
- static bool have_getrandom = syscall(SYS_getrandom, nullptr, 0, 0) != -1 || errno != ENOSYS;
static bool have_urandom = access("/dev/urandom", R_OK) == 0;
static size_t at_random_bytes_consumed = 0;
- if (have_getrandom || have_urandom) {
+ // Only call arc4random_buf once we `have_urandom', since in getentropy_getrandom we may fallback
+ // to use /dev/urandom, if the kernel entropy pool hasn't been initialized or not enough bytes
+ if (have_urandom) {
arc4random_buf(buf, n);
return;
}
diff --git a/libc/bionic/getentropy_linux.c b/libc/bionic/getentropy_linux.c
index 98fb6fb..cf0aa45 100644
--- a/libc/bionic/getentropy_linux.c
+++ b/libc/bionic/getentropy_linux.c
@@ -102,7 +102,7 @@
ret = getentropy_getrandom(buf, len);
if (ret != -1)
return (ret);
- if (errno != ENOSYS)
+ if (errno != ENOSYS && errno != EAGAIN)
return (-1);
/*
@@ -200,7 +200,11 @@
if (len > 256)
return (-1);
do {
- ret = syscall(SYS_getrandom, buf, len, 0);
+ /*
+ * Use GRND_NONBLOCK to avoid blocking before the
+ * entropy pool has been initialized
+ */
+ ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
} while (ret == -1 && errno == EINTR);
if ((size_t)ret != len)