From 913cebc8f44d50479704040c77d9ed20eea839bc Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Fri, 8 Jun 2018 11:38:22 +0200 Subject: [PATCH] rand/rand_unix.c: bypass DSO_global_lookup on ELF systems. If built with no-dso, syscall_random remains "blind" to getentropy. Since it's possible to detect symbol availability on ELF-based systems without involving DSO module, bypass it. Reviewed-by: Rich Salz Reviewed-by: Kurt Roeckx (Merged from https://github.com/openssl/openssl/pull/6436) --- crypto/rand/rand_unix.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c index e8222e9873..798908120d 100644 --- a/crypto/rand/rand_unix.c +++ b/crypto/rand/rand_unix.c @@ -229,17 +229,9 @@ static size_t sysctl_random(char *buf, size_t buflen) */ int syscall_random(void *buf, size_t buflen) { - union { - void *p; - int (*f)(void *buffer, size_t length); - } p_getentropy; - /* * Do runtime detection to find getentropy(). * - * We could cache the result of the lookup, but we normally don't - * call this function often. - * * Known OSs that should support this: * - Darwin since 16 (OSX 10.12, IOS 10.0). * - Solaris since 11.3 @@ -247,11 +239,27 @@ int syscall_random(void *buf, size_t buflen) * - Linux since 3.17 with glibc 2.25 * - FreeBSD since 12.0 (1200061) */ +# if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) + extern int getentropy(void *bufer, size_t length) __attribute__((weak)); + + if (getentropy != NULL) + return getentropy(buf, buflen) == 0 ? buflen : 0; +# else + union { + void *p; + int (*f)(void *buffer, size_t length); + } p_getentropy; + + /* + * We could cache the result of the lookup, but we normally don't + * call this function often. + */ ERR_set_mark(); p_getentropy.p = DSO_global_lookup("getentropy"); ERR_pop_to_mark(); if (p_getentropy.p != NULL) return p_getentropy.f(buf, buflen) == 0 ? buflen : 0; +# endif /* Linux supports this since version 3.17 */ # if defined(__linux) && defined(SYS_getrandom) -- 2.25.1