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)