Skip to content

Commit

Permalink
Use sysctl for seeding on MacOS/BSD
Browse files Browse the repository at this point in the history
  • Loading branch information
sipa committed Nov 12, 2019
1 parent 2554c1b commit a81c494
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 2 deletions.
14 changes: 13 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -948,6 +948,18 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>
[ AC_MSG_RESULT(no)]
)

AC_MSG_CHECKING(for sysctl)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <sys/sysctl.h>]],
[[ 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 <sys/types.h>
#include <sys/sysctl.h>]],
Expand Down
128 changes: 127 additions & 1 deletion src/randomenv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@
#if HAVE_DECL_GETIFADDRS
#include <ifaddrs.h>
#endif
#if HAVE_SYSCTL
#include <sys/sysctl.h>
#if HAVE_VM_VM_PARAM_H
#include <vm/vm_param.h>
#endif
#if HAVE_SYS_RESOURCES_H
#include <sys/resources.h>
#endif
#if HAVE_SYS_VMMETER_H
#include <sys/vmmeter.h>
#endif
#endif

//! Necessary on some platforms
extern char** environ;
Expand Down Expand Up @@ -149,6 +161,23 @@ void AddPath(CSHA512& hasher, const char *path)
}
#endif

#if HAVE_SYSCTL
template<int... S>
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

Expand Down Expand Up @@ -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<CTL_KERN, KERN_PROC, KERN_PROC_ALL>(hasher);
# endif
# endif
# ifdef CTL_HW
# ifdef HW_DISKSTATS
AddSysctl<CTL_HW, HW_DISKSTATS>(hasher);
# endif
# endif
# ifdef CTL_VM
# ifdef VM_LOADAVG
AddSysctl<CTL_VM, VM_LOADAVG>(hasher);
# endif
# ifdef VM_TOTAL
AddSysctl<CTL_VM, VM_TOTAL>(hasher);
# endif
# ifdef VM_METER
AddSysctl<CTL_VM, VM_METER>(hasher);
# endif
# endif
#endif

// Stack and heap location
void* addr = malloc(4097);
hasher << &addr << addr;
Expand Down Expand Up @@ -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<CTL_HW, HW_MACHINE>(hasher);
# endif
# ifdef HW_MODEL
AddSysctl<CTL_HW, HW_MODEL>(hasher);
# endif
# ifdef HW_NCPU
AddSysctl<CTL_HW, HW_NCPU>(hasher);
# endif
# ifdef HW_PHYSMEM
AddSysctl<CTL_HW, HW_PHYSMEM>(hasher);
# endif
# ifdef HW_USERMEM
AddSysctl<CTL_HW, HW_USERMEM>(hasher);
# endif
# ifdef HW_MACHINE_ARCH
AddSysctl<CTL_HW, HW_MACHINE_ARCH>(hasher);
# endif
# ifdef HW_REALMEM
AddSysctl<CTL_HW, HW_REALMEM>(hasher);
# endif
# ifdef HW_CPU_FREQ
AddSysctl<CTL_HW, HW_CPU_FREQ>(hasher);
# endif
# ifdef HW_BUS_FREQ
AddSysctl<CTL_HW, HW_BUS_FREQ>(hasher);
# endif
# ifdef HW_CACHELINE
AddSysctl<CTL_HW, HW_CACHELINE>(hasher);
# endif
# endif
# ifdef CTL_KERN
# ifdef KERN_BOOTFILE
AddSysctl<CTL_KERN, KERN_BOOTFILE>(hasher);
# endif
# ifdef KERN_BOOTTIME
AddSysctl<CTL_KERN, KERN_BOOTTIME>(hasher);
# endif
# ifdef KERN_CLOCKRATE
AddSysctl<CTL_KERN, KERN_CLOCKRATE>(hasher);
# endif
# ifdef KERN_HOSTID
AddSysctl<CTL_KERN, KERN_HOSTID>(hasher);
# endif
# ifdef KERN_HOSTUUID
AddSysctl<CTL_KERN, KERN_HOSTUUID>(hasher);
# endif
# ifdef KERN_HOSTNAME
AddSysctl<CTL_KERN, KERN_HOSTNAME>(hasher);
# endif
# ifdef KERN_OSRELDATE
AddSysctl<CTL_KERN, KERN_OSRELDATE>(hasher);
# endif
# ifdef KERN_OSRELEASE
AddSysctl<CTL_KERN, KERN_OSRELEASE>(hasher);
# endif
# ifdef KERN_OSREV
AddSysctl<CTL_KERN, KERN_OSREV>(hasher);
# endif
# ifdef KERN_OSTYPE
AddSysctl<CTL_KERN, KERN_OSTYPE>(hasher);
# endif
# ifdef KERN_POSIX1
AddSysctl<CTL_KERN, KERN_OSREV>(hasher);
# endif
# ifdef KERN_VERSION
AddSysctl<CTL_KERN, KERN_VERSION>(hasher);
# endif
# endif
#endif

// Env variables
Expand Down

0 comments on commit a81c494

Please sign in to comment.