diff --git a/libc/bionic/getentropy_linux.c b/libc/bionic/getentropy_linux.c index 98fb6fb71..409bd7d96 100644 --- a/libc/bionic/getentropy_linux.c +++ b/libc/bionic/getentropy_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_linux.c,v 1.42 2016/04/19 20:20:24 tj Exp $ */ +/* $OpenBSD: getentropy_linux.c,v 1.28 2014/07/20 03:24:10 deraadt Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -17,7 +17,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Emulation of getentropy(2) as documented at: - * http://man.openbsd.org/getentropy.2 + * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2 */ #define _POSIX_C_SOURCE 199309L @@ -27,8 +27,8 @@ #include #include #include -#ifdef SYS__sysctl -#include +#ifdef HAVE_SYS_SYSCTL_H +#include #endif #include #include @@ -51,8 +51,8 @@ #include #endif -#include #include +#include #ifdef HAVE_GETAUXVAL #include #endif @@ -76,7 +76,9 @@ int getentropy(void *buf, size_t len); static int gotdata(char *buf, size_t len); +#ifdef SYS__getrandom static int getentropy_getrandom(void *buf, size_t len); +#endif static int getentropy_urandom(void *buf, size_t len); #ifdef SYS__sysctl static int getentropy_sysctl(void *buf, size_t len); @@ -93,17 +95,17 @@ getentropy(void *buf, size_t len) if (len > 256) { errno = EIO; - return (-1); + return -1; } +#ifdef SYS__getrandom /* * Try descriptor-less getrandom() */ ret = getentropy_getrandom(buf, len); if (ret != -1) return (ret); - if (errno != ENOSYS) - return (-1); +#endif /* * Try to get entropy with /dev/urandom @@ -120,7 +122,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 - * exhausted. + * exhuasted. * * However this can fail if the Linux kernel removes support * for sysctl. Starting in 2007, there have been efforts to @@ -188,26 +190,39 @@ gotdata(char *buf, size_t len) for (i = 0; i < len; ++i) any_set |= buf[i]; if (any_set == 0) - return (-1); - return (0); + return -1; + return 0; } +#ifdef SYS__getrandom static int getentropy_getrandom(void *buf, size_t len) { - int pre_errno = errno; - int ret; +#if 0 + +/* Hand-definitions until the API becomes commonplace */ +#ifndef SYS__getrandom +#ifdef __LP64__ +#define SYS__getrandom 317 +#else +#define SYS__getrandom 354 +#endif +#endif + struct __getrandom_args args = { + .buf = buf; + .len = len; + .flags = 0; + }; + if (len > 256) return (-1); - do { - ret = syscall(SYS_getrandom, buf, len, 0); - } while (ret == -1 && errno == EINTR); - - if ((size_t)ret != len) - return (-1); - errno = pre_errno; - return (0); + ret = syscall(SYS__getrandom, &args); + if (ret == len) + return (0); +#endif + return -1; } +#endif static int getentropy_urandom(void *buf, size_t len) @@ -260,11 +275,11 @@ start: close(fd); if (gotdata(buf, len) == 0) { errno = save_errno; - return (0); /* satisfied */ + return 0; /* satisfied */ } nodevrandom: errno = EIO; - return (-1); + return -1; } #ifdef SYS__sysctl @@ -282,7 +297,7 @@ getentropy_sysctl(void *buf, size_t len) struct __sysctl_args args = { .name = mib, .nlen = 3, - .oldval = (char *)buf + i, + .oldval = (char*) buf + i, .oldlenp = &chunk, }; if (syscall(SYS__sysctl, &args) != 0) @@ -295,12 +310,13 @@ getentropy_sysctl(void *buf, size_t len) } sysctlfailed: errno = EIO; - return (-1); + return -1; } #endif /* SYS__sysctl */ #ifdef HAVE_OPENSSL -static const int cl[] = { + +static int cl[] = { CLOCK_REALTIME, #ifdef CLOCK_MONOTONIC CLOCK_MONOTONIC, @@ -331,7 +347,7 @@ getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data) SHA512_CTX *ctx = data; SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr)); - return (0); + return 0; } static int @@ -540,9 +556,10 @@ getentropy_fallback(void *buf, size_t len) memset(results, 0, sizeof results); if (gotdata(buf, len) == 0) { errno = save_errno; - return (0); /* satisfied */ + return 0; /* satisfied */ } errno = EIO; - return (-1); + return -1; } + #endif /* HAVE_OPENSSL */