summaryrefslogtreecommitdiffstats
path: root/crypto/rand
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2018-06-08 11:38:22 +0200
committerAndy Polyakov <appro@openssl.org>2018-06-09 14:45:05 +0200
commit913cebc8f44d50479704040c77d9ed20eea839bc (patch)
tree09d07069cb16a7e58ffa76e153254178bb610511 /crypto/rand
parent46ceca3c91cc7b8e8f522009e7338a9a96952e6e (diff)
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 <rsalz@openssl.org> Reviewed-by: Kurt Roeckx <kurt@roeckx.be> (Merged from https://github.com/openssl/openssl/pull/6436)
Diffstat (limited to 'crypto/rand')
-rw-r--r--crypto/rand/rand_unix.c24
1 files 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)