From edb2eeb7da8494998d0073f8aaeb8478cee5e00b Mon Sep 17 00:00:00 2001 From: beck Date: Sat, 29 Apr 2017 18:43:31 +0000 Subject: [PATCH] Switch Linux getrandom() usage to non-blocking mode, continuing to use fallback mechanims if unsuccessful. 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. ok deraadt@ jsing@ --- lib/libcrypto/arc4random/getentropy_linux.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/libcrypto/arc4random/getentropy_linux.c b/lib/libcrypto/arc4random/getentropy_linux.c index ac97658efe33..a845239eb3ef 100644 --- a/lib/libcrypto/arc4random/getentropy_linux.c +++ b/lib/libcrypto/arc4random/getentropy_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_linux.c,v 1.43 2016/08/07 03:27:21 tb Exp $ */ +/* $OpenBSD: getentropy_linux.c,v 1.44 2017/04/29 18:43:31 beck Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -96,13 +96,16 @@ getentropy(void *buf, size_t len) #ifdef SYS_getrandom /* - * 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 /* @@ -156,7 +159,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 @@ -199,7 +202,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 != len)