diff --git a/configure.ac b/configure.ac index 8bde6d9bc4..e1db71a7bf 100644 --- a/configure.ac +++ b/configure.ac @@ -788,7 +788,7 @@ if test x$TARGET_OS = xdarwin; then AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) fi -AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) +AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h sys/sysctl.h vm/vm_param.h sys/vmmeter.h sys/resources.h]) # FD_ZERO may be dependent on a declaration of memcpy, e.g. in SmartOS # check that it fails to build without memcpy, then that it builds with @@ -948,6 +948,18 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include [ AC_MSG_RESULT(no)] ) +AC_MSG_CHECKING(for sysctl) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + #include ]], + [[ static const int name[2] = {CTL_KERN, KERN_VERSION}; + #ifdef __linux__ + #error "Don't use sysctl on Linux, it's deprecated even when it works" + #endif + sysctl(name, 2, nullptr, nullptr, nullptr, 0); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYSCTL, 1,[Define this symbol if the BSD sysctl() is available]) ], + [ AC_MSG_RESULT(no)] +) + AC_MSG_CHECKING(for sysctl KERN_ARND) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], diff --git a/src/randomenv.cpp b/src/randomenv.cpp index 1faf2f4613..197c5ce154 100644 --- a/src/randomenv.cpp +++ b/src/randomenv.cpp @@ -44,6 +44,18 @@ #if HAVE_DECL_GETIFADDRS #include #endif +#if HAVE_SYSCTL +#include +#if HAVE_VM_VM_PARAM_H +#include +#endif +#if HAVE_SYS_RESOURCES_H +#include +#endif +#if HAVE_SYS_VMMETER_H +#include +#endif +#endif //! Necessary on some platforms extern char** environ; @@ -149,6 +161,23 @@ void AddPath(CSHA512& hasher, const char *path) } #endif +#if HAVE_SYSCTL +template +void AddSysctl(CSHA512& hasher) +{ + int CTL[sizeof...(S)] = {S...}; + unsigned char buffer[65536]; + size_t siz = 65536; + int ret = sysctl(CTL, sizeof...(S), buffer, &siz, nullptr, 0); + if (ret == 0 || (ret == -1 && errno == ENOMEM)) { + hasher << sizeof(CTL); + hasher.Write((const unsigned char*)CTL, sizeof(CTL)); + if (siz > sizeof(buffer)) siz = sizeof(buffer); + hasher << siz; + hasher.Write(buffer, siz); + } +} +#endif } // namespace @@ -217,6 +246,30 @@ void RandAddDynamicEnv(CSHA512& hasher) AddFile(hasher, "/proc/self/status"); #endif +#if HAVE_SYSCTL +# ifdef CTL_KERN +# if defined(KERN_PROC) && defined(KERN_PROC_ALL) + AddSysctl(hasher); +# endif +# endif +# ifdef CTL_HW +# ifdef HW_DISKSTATS + AddSysctl(hasher); +# endif +# endif +# ifdef CTL_VM +# ifdef VM_LOADAVG + AddSysctl(hasher); +# endif +# ifdef VM_TOTAL + AddSysctl(hasher); +# endif +# ifdef VM_METER + AddSysctl(hasher); +# endif +# endif +#endif + // Stack and heap location void* addr = malloc(4097); hasher << &addr << addr; @@ -299,8 +352,81 @@ void RandAddStaticEnv(CSHA512& hasher) AddFile(hasher, "/etc/resolv.conf"); AddFile(hasher, "/etc/timezone"); AddFile(hasher, "/etc/localtime"); +#endif - /* TODO: sysctl's for OSX to fetch information not available from /proc */ + // For MacOS/BSDs, gather data through sysctl instead of /proc. Not all of these + // will exist on every system. +#if HAVE_SYSCTL +# ifdef CTL_HW +# ifdef HW_MACHINE + AddSysctl(hasher); +# endif +# ifdef HW_MODEL + AddSysctl(hasher); +# endif +# ifdef HW_NCPU + AddSysctl(hasher); +# endif +# ifdef HW_PHYSMEM + AddSysctl(hasher); +# endif +# ifdef HW_USERMEM + AddSysctl(hasher); +# endif +# ifdef HW_MACHINE_ARCH + AddSysctl(hasher); +# endif +# ifdef HW_REALMEM + AddSysctl(hasher); +# endif +# ifdef HW_CPU_FREQ + AddSysctl(hasher); +# endif +# ifdef HW_BUS_FREQ + AddSysctl(hasher); +# endif +# ifdef HW_CACHELINE + AddSysctl(hasher); +# endif +# endif +# ifdef CTL_KERN +# ifdef KERN_BOOTFILE + AddSysctl(hasher); +# endif +# ifdef KERN_BOOTTIME + AddSysctl(hasher); +# endif +# ifdef KERN_CLOCKRATE + AddSysctl(hasher); +# endif +# ifdef KERN_HOSTID + AddSysctl(hasher); +# endif +# ifdef KERN_HOSTUUID + AddSysctl(hasher); +# endif +# ifdef KERN_HOSTNAME + AddSysctl(hasher); +# endif +# ifdef KERN_OSRELDATE + AddSysctl(hasher); +# endif +# ifdef KERN_OSRELEASE + AddSysctl(hasher); +# endif +# ifdef KERN_OSREV + AddSysctl(hasher); +# endif +# ifdef KERN_OSTYPE + AddSysctl(hasher); +# endif +# ifdef KERN_POSIX1 + AddSysctl(hasher); +# endif +# ifdef KERN_VERSION + AddSysctl(hasher); +# endif +# endif #endif // Env variables