- update compat/getentropy to the most recent ones from OpenBSD.

git-svn-id: file:///svn/unbound/trunk@3183 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2014-07-12 18:03:27 +00:00
parent 06bfd7bd22
commit 3e8feb6e84
7 changed files with 103 additions and 66 deletions

View file

@ -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 <deraadt@openbsd.org>
@ -27,7 +27,9 @@
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#include <sys/statvfs.h>
#include <sys/socket.h>
#include <sys/mount.h>
@ -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) {

View file

@ -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 <deraadt@openbsd.org>
@ -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);

View file

@ -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 <deraadt@openbsd.org>
@ -44,7 +44,6 @@
#define SHA512_Update SHA512Update
#define SHA512_Final SHA512Final
#include <sys/vfs.h>
#include <sys/statfs.h>
#include <sys/loadavg.h>
@ -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);

View file

@ -365,6 +365,9 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#undef HAVE_SYS_SYSCTL_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

13
configure vendored
View file

@ -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

View file

@ -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

View file

@ -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).