diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -798,7 +798,7 @@ AX_CHECK_LINK_FLAG([[-Wl,-dead_strip_dylibs]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip_dylibs"]) 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]) AC_CHECK_DECLS([getifaddrs, freeifaddrs],,, [#include @@ -881,6 +881,18 @@ [ 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/config/CMakeLists.txt b/src/config/CMakeLists.txt --- a/src/config/CMakeLists.txt +++ b/src/config/CMakeLists.txt @@ -119,6 +119,16 @@ # macOS needs unistd.h and sys/random.h to define getentropy check_symbol_exists(getentropy "unistd.h;sys/random.h" HAVE_GETENTROPY_RAND) +# OSX and BSDs measurement related headers +check_include_files("sys/types.h;vm/vm_params.h" HAVE_VM_VM_PARAM_H) +check_include_files("sys/types.h;sys/vmmeter.h" HAVE_SYS_VMMETER_H) +check_include_files("sys/types.h;sys/resources.h" HAVE_SYS_RESOURCES_H) + +# Don't use sysctl on Linux, it's deprecated even when it works +if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux") + check_symbol_exists(sysctl "sys/types.h;sys/sysctl.h" HAVE_SYSCTL) +endif() + # getifaddrs and freeifaddrs may be unavailable with some Android versions check_symbol_exists(getifaddrs "sys/types.h;ifaddrs.h" HAVE_DECL_GETIFADDRS) check_symbol_exists(freeifaddrs "sys/types.h;ifaddrs.h" HAVE_DECL_FREEIFADDRS) diff --git a/src/config/bitcoin-config.h.cmake.in b/src/config/bitcoin-config.h.cmake.in --- a/src/config/bitcoin-config.h.cmake.in +++ b/src/config/bitcoin-config.h.cmake.in @@ -52,6 +52,12 @@ #cmakedefine HAVE_GETENTROPY 1 #cmakedefine HAVE_GETENTROPY_RAND 1 #cmakedefine HAVE_SYS_GETRANDOM 1 + +#cmakedefine HAVE_VM_VM_PARAM_H 1 +#cmakedefine HAVE_SYS_VMMETER_H 1 +#cmakedefine HAVE_SYS_RESOURCES_H 1 +#cmakedefine HAVE_SYSCTL 1 + #cmakedefine HAVE_SYSCTL_ARND 1 #cmakedefine CHAR_EQUALS_INT8 0 diff --git a/src/randomenv.cpp b/src/randomenv.cpp --- a/src/randomenv.cpp +++ b/src/randomenv.cpp @@ -45,6 +45,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; @@ -168,6 +180,24 @@ } #endif +#if HAVE_SYSCTL +template void AddSysctl(CSHA512 &hasher) { + int CTL[sizeof...(S)] = {S...}; + uint8_t 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 uint8_t *)CTL, sizeof(CTL)); + if (siz > sizeof(buffer)) { + siz = sizeof(buffer); + } + hasher << siz; + hasher.Write(buffer, siz); + } +} +#endif + } // namespace void RandAddDynamicEnv(CSHA512 &hasher) { @@ -241,6 +271,30 @@ 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; @@ -326,8 +380,81 @@ 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