From: Wouter Wijngaards Date: Sat, 12 Jul 2014 18:03:27 +0000 (+0000) Subject: - update compat/getentropy to the most recent ones from OpenBSD. X-Git-Tag: release-1.5.0rc1~77 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e8feb6e840544913d06480ae24e2e5afa5016df;p=thirdparty%2Funbound.git - update compat/getentropy to the most recent ones from OpenBSD. git-svn-id: file:///svn/unbound/trunk@3183 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/compat/getentropy_linux.c b/compat/getentropy_linux.c index 5de2cc095..9213cda6c 100644 --- a/compat/getentropy_linux.c +++ b/compat/getentropy_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_linux.c,v 1.18 2014/07/08 09:38:55 beck Exp $ */ +/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -27,7 +27,9 @@ #include #include #include +#ifdef HAVE_SYS_SYSCTL_H #include +#endif #include #include #include @@ -147,8 +149,8 @@ getentropy(void *buf, size_t len) * sysctl ABI, or consider providing a new failsafe API which * works in a chroot or when file descriptors are exhausted. */ -#undef FAIL_HARD_WHEN_LINUX_DEPRECATES_SYSCTL -#ifdef FAIL_HARD_WHEN_LINUX_DEPRECATES_SYSCTL +#undef FAIL_INSTEAD_OF_TRYING_FALLBACK +#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK raise(SIGKILL); #endif ret = getentropy_fallback(buf, len); @@ -185,12 +187,12 @@ getentropy_urandom(void *buf, size_t len) start: - flags = O_RDONLY; + flags = O_RDONLY; #ifdef O_NOFOLLOW - flags |= O_NOFOLLOW; + flags |= O_NOFOLLOW; #endif #ifdef O_CLOEXEC - flags |= O_CLOEXEC; + flags |= O_CLOEXEC; #endif fd = open("/dev/urandom", flags, 0); if (fd == -1) { diff --git a/compat/getentropy_osx.c b/compat/getentropy_osx.c index d9c7cc861..4a2631b0b 100644 --- a/compat/getentropy_osx.c +++ b/compat/getentropy_osx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_osx.c,v 1.2 2014/07/09 13:23:15 bcook Exp $ */ +/* $OpenBSD: getentropy_osx.c,v 1.3 2014/07/12 14:48:00 deraadt Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -67,10 +67,12 @@ else \ HD(b); \ } while (0) + #define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) #define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) /* (portability) some compilers cannot take sizeof a function pointer */ #define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) + int getentropy(void *buf, size_t len); /* cannot reference main, or log_info for unbound, it @@ -104,8 +106,8 @@ getentropy(void *buf, size_t len) * Entropy collection via /dev/urandom and sysctl have failed. * * No other API exists for collecting entropy, and we have - * no failsafe way to get it on OSX that is not sensitive - * to resource exhaustion. + * no failsafe way to get it on OSX that is not sensitive + * to resource exhaustion. * * We have very few options: * - Even syslog_r is unsafe to call at this low level, so @@ -124,8 +126,8 @@ getentropy(void *buf, size_t len) * providing a new failsafe API which works in a chroot or * when file descriptors are exhausted. */ -#undef FAIL_WHEN_SYSTEM_ENTROPY_FAILS -#ifdef FAIL_WHEN_SYSTEM_ENTROPY_FAILS +#undef FAIL_INSTEAD_OF_TRYING_FALLBACK +#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK raise(SIGKILL); #endif ret = getentropy_fallback(buf, len); @@ -162,12 +164,12 @@ getentropy_urandom(void *buf, size_t len) start: - flags = O_RDONLY; + flags = O_RDONLY; #ifdef O_NOFOLLOW - flags |= O_NOFOLLOW; + flags |= O_NOFOLLOW; #endif #ifdef O_CLOEXEC - flags |= O_CLOEXEC; + flags |= O_CLOEXEC; #endif fd = open("/dev/urandom", flags, 0); if (fd == -1) { @@ -206,33 +208,34 @@ nodevrandom: return -1; } +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 }; +static int kmib[] = { CTL_KERN, KERN_USRSTACK }; +static int hwmib[] = { CTL_HW, HW_USERMEM }; + static int getentropy_fallback(void *buf, size_t len) { - int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS }; - int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS }; - int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS }; - int kmib[] = { CTL_KERN, KERN_USRSTACK }; - int hwmib[] = { CTL_HW, HW_USERMEM }; - int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat; uint8_t results[SHA512_DIGEST_LENGTH]; - struct tcpstat tcpstat; - struct udpstat udpstat; - struct ipstat ipstat; - u_int64_t mach_time; - unsigned int idata; + int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat; + static int cnt; struct timespec ts; struct timeval tv; struct rusage ru; sigset_t sigset; struct stat st; - static int cnt; SHA512_CTX ctx; static pid_t lastpid; - void * addr; pid_t pid; - size_t i, m; + size_t i, ii, m; char *p; + struct tcpstat tcpstat; + struct udpstat udpstat; + struct ipstat ipstat; + u_int64_t mach_time; + unsigned int idata; + void * addr; pid = getpid(); if (lastpid == pid) { @@ -247,35 +250,34 @@ getentropy_fallback(void *buf, size_t len) int j; SHA512_Init(&ctx); for (j = 0; j < repeat; j++) { - size_t len; HX((e = gettimeofday(&tv, NULL)) == -1, tv); if (e != -1) { cnt += (int)tv.tv_sec; cnt += (int)tv.tv_usec; } - mach_time = mach_absolute_time(); - HD(mach_time); + mach_time = mach_absolute_time(); + HD(mach_time); - len = sizeof(addr); + ii = sizeof(addr); HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]), - &addr, &len, NULL, 0) == -1, addr); + &addr, &ii, NULL, 0) == -1, addr); - len = sizeof(idata); + ii = sizeof(idata); HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]), - &idata, &len, NULL, 0) == -1, idata); + &idata, &ii, NULL, 0) == -1, idata); - len = sizeof(tcpstat); + ii = sizeof(tcpstat); HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]), - &tcpstat, &len, NULL, 0) == -1, tcpstat); + &tcpstat, &ii, NULL, 0) == -1, tcpstat); - len = sizeof(udpstat); + ii = sizeof(udpstat); HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]), - &udpstat, &len, NULL, 0) == -1, udpstat); + &udpstat, &ii, NULL, 0) == -1, udpstat); - len = sizeof(ipstat); + ii = sizeof(ipstat); HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]), - &ipstat, &len, NULL, 0) == -1, ipstat); + &ipstat, &ii, NULL, 0) == -1, ipstat); HX((pid = getpid()) == -1, pid); HX((pid = getsid(pid)) == -1, pid); @@ -345,9 +347,9 @@ getentropy_fallback(void *buf, size_t len) } /* Check cnts and times... */ - mach_time = mach_absolute_time(); - HD(mach_time); - cnt += (int)mach_time; + mach_time = mach_absolute_time(); + HD(mach_time); + cnt += (int)mach_time; HX((e = getrusage(RUSAGE_SELF, &ru)) == -1, ru); @@ -415,7 +417,6 @@ getentropy_fallback(void *buf, size_t len) HD(cnt); } - SHA512_Final(results, &ctx); memcpy(buf + i, results, min(sizeof(results), len - i)); i += min(sizeof(results), len - i); diff --git a/compat/getentropy_solaris.c b/compat/getentropy_solaris.c index a8e6bb7d2..ffaa3260a 100644 --- a/compat/getentropy_solaris.c +++ b/compat/getentropy_solaris.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_solaris.c,v 1.1 2014/07/08 10:45:35 beck Exp $ */ +/* $OpenBSD: getentropy_solaris.c,v 1.3 2014/07/12 14:46:31 deraadt Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -44,7 +44,6 @@ #define SHA512_Update SHA512Update #define SHA512_Final SHA512Final - #include #include #include @@ -72,7 +71,8 @@ int getentropy(void *buf, size_t len); have different link semantics (but it also fails on other platforms) */ /* extern int main(int, char *argv[]); */ static int gotdata(char *buf, size_t len); -static int getentropy_urandom(void *buf, size_t len); +static int getentropy_urandom(void *buf, size_t len, const char *path, + int devfscheck); static int getentropy_fallback(void *buf, size_t len); int @@ -88,18 +88,37 @@ getentropy(void *buf, size_t len) /* * Try to get entropy with /dev/urandom * + * Solaris provides /dev/urandom as a symbolic link to + * /devices/pseudo/random@0:urandom which is provided by + * a devfs filesystem. Best practice is to use O_NOFOLLOW, + * so we must try the unpublished name directly. + * + * This can fail if the process is inside a chroot which lacks + * the devfs mount, or if file descriptors are exhausted. + */ + ret = getentropy_urandom(buf, len, + "/devices/pseudo/random@0:urandom", 1); + if (ret != -1) + return (ret); + + /* + * Unfortunately, chroot spaces on Solaris are sometimes setup + * with direct device node of the well-known /dev/urandom name + * (perhaps to avoid dragging all of devfs into the space). + * * This can fail if the process is inside a chroot or if file * descriptors are exhausted. */ - ret = getentropy_urandom(buf, len); + ret = getentropy_urandom(buf, len, "/dev/urandom", 0); if (ret != -1) return (ret); + /* - * Entropy collection via /dev/urandom and sysctl have failed. + * Entropy collection via /dev/urandom has failed. * * No other API exists for collecting entropy, and we have - * no failsafe way to get it on Solaris that is not sensitive - * to resource exhaustion. + * no failsafe way to get it on Solaris that is not sensitive + * to resource exhaustion. * * We have very few options: * - Even syslog_r is unsafe to call at this low level, so @@ -118,8 +137,8 @@ getentropy(void *buf, size_t len) * providing a new failsafe API which works in a chroot or * when file descriptors are exhausted. */ -#undef FAIL_WHEN_SYSTEM_ENTROPY_FAILS -#ifdef FAIL_WHEN_SYSTEM_ENTROPY_FAILS +#undef FAIL_INSTEAD_OF_TRYING_FALLBACK +#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK raise(SIGKILL); #endif ret = getentropy_fallback(buf, len); @@ -147,7 +166,7 @@ gotdata(char *buf, size_t len) } static int -getentropy_urandom(void *buf, size_t len) +getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck) { struct stat st; size_t i; @@ -156,19 +175,14 @@ getentropy_urandom(void *buf, size_t len) start: - flags = O_RDONLY; + flags = O_RDONLY; #ifdef O_NOFOLLOW - flags |= O_NOFOLLOW; + flags |= O_NOFOLLOW; #endif #ifdef O_CLOEXEC - flags |= O_CLOEXEC; + flags |= O_CLOEXEC; #endif - /* - * Solaris provides /dev/urandom as a symbolic link. - * /devices/pseudo/random@0:urandom should be the - * real device path, and we do want O_NOFOLLOW. - */ - fd = open("/devices/pseudo/random@0:urandom", flags, 0); + fd = open(path, flags, 0); if (fd == -1) { if (errno == EINTR) goto start; @@ -179,7 +193,8 @@ start: #endif /* Lightly verify that the device node looks sane */ - if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) { + if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode) || + (devfscheck && (strcmp(st.st_fstype, "devfs") != 0))) { close(fd); goto nodevrandom; } @@ -205,7 +220,7 @@ nodevrandom: return -1; } -static int cl[] = { +static const int cl[] = { CLOCK_REALTIME, #ifdef CLOCK_MONOTONIC CLOCK_MONOTONIC, @@ -269,6 +284,7 @@ getentropy_fallback(void *buf, size_t len) for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) HX(clock_gettime(cl[ii], &ts) == -1, ts); + HX((pid = getpid()) == -1, pid); HX((pid = getsid(pid)) == -1, pid); HX((pid = getppid()) == -1, pid); diff --git a/config.h.in b/config.h.in index 44ef8c1ff..fda3e9951 100644 --- a/config.h.in +++ b/config.h.in @@ -365,6 +365,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SYSCTL_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H diff --git a/configure b/configure index 9fc1cd3ed..383968497 100755 --- a/configure +++ b/configure @@ -18321,6 +18321,19 @@ esac fi +done + + for ac_header in sys/sysctl.h +do : + ac_fn_c_check_header_compile "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "$ac_includes_default +" +if test "x$ac_cv_header_sys_sysctl_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_SYSCTL_H 1 +_ACEOF + +fi + done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 diff --git a/configure.ac b/configure.ac index 547ac426f..871d7592e 100644 --- a/configure.ac +++ b/configure.ac @@ -1017,6 +1017,7 @@ if test "$USE_NSS" = "no"; then AC_DEFINE([COMPAT_SHA512], [1], [Do sha512 definitions in config.h]) AC_LIBOBJ(sha512) ]) + AC_CHECK_HEADERS([sys/sysctl.h],,, [AC_INCLUDES_DEFAULT]) AC_SEARCH_LIBS([clock_gettime], [rt]) ;; esac diff --git a/doc/Changelog b/doc/Changelog index 35568118b..9d1cd7fbb 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -3,6 +3,7 @@ - Fix to check openssl version number only for OpenSSL. - LibreSSL provides compat items, check for that in configure. - Fix bug in fix for log locks that caused deadlock in signal handler. + - update compat/getentropy to the most recent ones from OpenBSD. 11 July 2014: Matthijs - fake-rfc2553 patch (thanks Benjamin Baier).