Commit e42381dc51065e6d48ae982a01888dddde26ef7b

Guillem Jover 2018-05-15T00:41:26

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

diff --git a/src/getentropy_aix.c b/src/getentropy_aix.c
index d4ccab7..d759fe0 100644
--- a/src/getentropy_aix.c
+++ b/src/getentropy_aix.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getentropy_aix.c,v 1.3 2015/08/25 17:26:43 deraadt Exp $	*/
+/*	$OpenBSD: getentropy_aix.c,v 1.5 2016/08/07 03:27:21 tb Exp $	*/
 
 /*
  * Copyright (c) 2015 Michael Felt <aixtools@gmail.com>
@@ -18,7 +18,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
  */
 /*
  * -lperfstat is needed for the psuedo entropy data
diff --git a/src/getentropy_bsd.c b/src/getentropy_bsd.c
index d45901b..705f65b 100644
--- a/src/getentropy_bsd.c
+++ b/src/getentropy_bsd.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getentropy_freebsd.c,v 1.1 2014/11/03 06:23:30 bcook Exp $	*/
+/*	$OpenBSD: getentropy_freebsd.c,v 1.3 2016/08/07 03:27:21 tb Exp $	*/
 
 /*
  * Copyright (c) 2014 Pawel Jakub Dawidek <pjd@FreeBSD.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
  */
 
 #include <sys/types.h>
diff --git a/src/getentropy_hpux.c b/src/getentropy_hpux.c
index 294d83a..5be096a 100644
--- a/src/getentropy_hpux.c
+++ b/src/getentropy_hpux.c
@@ -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
  */
 
 #include <sys/types.h>
diff --git a/src/getentropy_hurd.c b/src/getentropy_hurd.c
index 194d9c5..738dc3b 100644
--- a/src/getentropy_hurd.c
+++ b/src/getentropy_hurd.c
@@ -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
@@ -110,7 +110,7 @@ getentropy(void *buf, size_t len)
 	 *     - Do the best under the circumstances....
 	 *
 	 * This code path exists to bring light to the issue that Hurd
-	 * does not provide a failsafe API for entropy collection.
+	 * still does not provide a failsafe API for entropy collection.
 	 *
 	 * We hope this demonstrates that Hurd should either get a
 	 * sysctl ABI, or consider providing a new failsafe API which
diff --git a/src/getentropy_linux.c b/src/getentropy_linux.c
index d7a8ae5..74d965e 100644
--- a/src/getentropy_linux.c
+++ b/src/getentropy_linux.c
@@ -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)
diff --git a/src/getentropy_osx.c b/src/getentropy_osx.c
index db67c4b..bcdbce5 100644
--- a/src/getentropy_osx.c
+++ b/src/getentropy_osx.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getentropy_osx.c,v 1.8 2014/07/21 20:19:47 guenther Exp $	*/
+/*	$OpenBSD: getentropy_osx.c,v 1.11 2016/09/03 15:24:09 bcook Exp $	*/
 
 /*
  * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -17,9 +17,10 @@
  * 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
  */
 
+#include <TargetConditionals.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -45,14 +46,18 @@
 #include <mach/mach_time.h>
 #include <mach/mach_host.h>
 #include <mach/host_info.h>
+#if TARGET_OS_OSX
 #include <sys/socketvar.h>
 #include <sys/vmmeter.h>
+#endif
 #include <netinet/in.h>
 #include <netinet/tcp.h>
+#if TARGET_OS_OSX
 #include <netinet/udp.h>
 #include <netinet/ip_var.h>
 #include <netinet/tcp_var.h>
 #include <netinet/udp_var.h>
+#endif
 #include <CommonCrypto/CommonDigest.h>
 #define SHA512_Update(a, b, c)	(CC_SHA512_Update((a), (b), (c)))
 #define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
@@ -207,9 +212,11 @@ nodevrandom:
 	return (-1);
 }
 
+#if TARGET_OS_OSX
 static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
 static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
 static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
+#endif
 static int kmib[] = { CTL_KERN, KERN_USRSTACK };
 static int hwmib[] = { CTL_HW, HW_USERMEM };
 
@@ -229,9 +236,11 @@ getentropy_fallback(void *buf, size_t len)
 	pid_t pid;
 	size_t i, ii, m;
 	char *p;
+#if TARGET_OS_OSX
 	struct tcpstat tcpstat;
 	struct udpstat udpstat;
 	struct ipstat ipstat;
+#endif
 	uint64_t mach_time;
 	unsigned int idata;
 	void *addr;
@@ -266,6 +275,7 @@ getentropy_fallback(void *buf, size_t len)
 			HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
 			    &idata, &ii, NULL, 0) == -1, idata);
 
+#if TARGET_OS_OSX
 			ii = sizeof(tcpstat);
 			HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
 			    &tcpstat, &ii, NULL, 0) == -1, tcpstat);
@@ -277,6 +287,7 @@ getentropy_fallback(void *buf, size_t len)
 			ii = sizeof(ipstat);
 			HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
 			    &ipstat, &ii, NULL, 0) == -1, ipstat);
+#endif
 
 			HX((pid = getpid()) == -1, pid);
 			HX((pid = getsid(pid)) == -1, pid);
diff --git a/src/getentropy_solaris.c b/src/getentropy_solaris.c
index ca787f8..f0fcdcf 100644
--- a/src/getentropy_solaris.c
+++ b/src/getentropy_solaris.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getentropy_solaris.c,v 1.10 2015/08/25 17:26:43 deraadt Exp $	*/
+/*	$OpenBSD: getentropy_solaris.c,v 1.12 2016/08/07 03:27:21 tb 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
  */
 
 #include <sys/types.h>