Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto
# 2 : : // Copyright (c) 2009-2020 The Bitcoin Core developers
# 3 : : // Distributed under the MIT software license, see the accompanying
# 4 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
# 5 : :
# 6 : : #if defined(HAVE_CONFIG_H)
# 7 : : #include <config/bitcoin-config.h>
# 8 : : #endif
# 9 : :
# 10 : : #include <randomenv.h>
# 11 : :
# 12 : : #include <clientversion.h>
# 13 : : #include <compat/cpuid.h>
# 14 : : #include <crypto/sha512.h>
# 15 : : #include <support/cleanse.h>
# 16 : : #include <util/time.h> // for GetTime()
# 17 : : #ifdef WIN32
# 18 : : #include <compat.h> // for Windows API
# 19 : : #endif
# 20 : :
# 21 : : #include <algorithm>
# 22 : : #include <atomic>
# 23 : : #include <chrono>
# 24 : : #include <climits>
# 25 : : #include <thread>
# 26 : : #include <vector>
# 27 : :
# 28 : : #include <stdint.h>
# 29 : : #include <string.h>
# 30 : : #ifndef WIN32
# 31 : : #include <sys/types.h> // must go before a number of other headers
# 32 : : #include <fcntl.h>
# 33 : : #include <netinet/in.h>
# 34 : : #include <sys/resource.h>
# 35 : : #include <sys/socket.h>
# 36 : : #include <sys/stat.h>
# 37 : : #include <sys/time.h>
# 38 : : #include <sys/utsname.h>
# 39 : : #include <unistd.h>
# 40 : : #endif
# 41 : : #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS
# 42 : : #include <ifaddrs.h>
# 43 : : #endif
# 44 : : #if HAVE_SYSCTL
# 45 : : #include <sys/sysctl.h>
# 46 : : #if HAVE_VM_VM_PARAM_H
# 47 : : #include <vm/vm_param.h>
# 48 : : #endif
# 49 : : #if HAVE_SYS_RESOURCES_H
# 50 : : #include <sys/resources.h>
# 51 : : #endif
# 52 : : #if HAVE_SYS_VMMETER_H
# 53 : : #include <sys/vmmeter.h>
# 54 : : #endif
# 55 : : #endif
# 56 : : #if defined(HAVE_STRONG_GETAUXVAL) || defined(HAVE_WEAK_GETAUXVAL)
# 57 : : #include <sys/auxv.h>
# 58 : : #endif
# 59 : :
# 60 : : //! Necessary on some platforms
# 61 : : extern char** environ;
# 62 : :
# 63 : : namespace {
# 64 : :
# 65 : : void RandAddSeedPerfmon(CSHA512& hasher)
# 66 : 889 : {
# 67 : : #ifdef WIN32
# 68 : : // Seed with the entire set of perfmon data
# 69 : :
# 70 : : // This can take up to 2 seconds, so only do it every 10 minutes.
# 71 : : // Initialize last_perfmon to 0 seconds, we don't skip the first call.
# 72 : : static std::atomic<std::chrono::seconds> last_perfmon{0s};
# 73 : : auto last_time = last_perfmon.load();
# 74 : : auto current_time = GetTime<std::chrono::seconds>();
# 75 : : if (current_time < last_time + std::chrono::minutes{10}) return;
# 76 : : last_perfmon = current_time;
# 77 : :
# 78 : : std::vector<unsigned char> vData(250000, 0);
# 79 : : long ret = 0;
# 80 : : unsigned long nSize = 0;
# 81 : : const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
# 82 : : while (true) {
# 83 : : nSize = vData.size();
# 84 : : ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr, nullptr, vData.data(), &nSize);
# 85 : : if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
# 86 : : break;
# 87 : : vData.resize(std::min((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
# 88 : : }
# 89 : : RegCloseKey(HKEY_PERFORMANCE_DATA);
# 90 : : if (ret == ERROR_SUCCESS) {
# 91 : : hasher.Write(vData.data(), nSize);
# 92 : : memory_cleanse(vData.data(), nSize);
# 93 : : } else {
# 94 : : // Performance data is only a best-effort attempt at improving the
# 95 : : // situation when the OS randomness (and other sources) aren't
# 96 : : // adequate. As a result, failure to read it is isn't considered critical,
# 97 : : // so we don't call RandFailure().
# 98 : : // TODO: Add logging when the logger is made functional before global
# 99 : : // constructors have been invoked.
# 100 : : }
# 101 : : #endif
# 102 : 889 : }
# 103 : :
# 104 : : /** Helper to easily feed data into a CSHA512.
# 105 : : *
# 106 : : * Note that this does not serialize the passed object (like stream.h's << operators do).
# 107 : : * Its raw memory representation is used directly.
# 108 : : */
# 109 : : template<typename T>
# 110 : 262850 : CSHA512& operator<<(CSHA512& hasher, const T& data) {
# 111 : 262850 : static_assert(!std::is_same<typename std::decay<T>::type, char*>::value, "Calling operator<<(CSHA512, char*) is probably not what you want");
# 112 : 262850 : static_assert(!std::is_same<typename std::decay<T>::type, unsigned char*>::value, "Calling operator<<(CSHA512, unsigned char*) is probably not what you want");
# 113 : 262850 : static_assert(!std::is_same<typename std::decay<T>::type, const char*>::value, "Calling operator<<(CSHA512, const char*) is probably not what you want");
# 114 : 262850 : static_assert(!std::is_same<typename std::decay<T>::type, const unsigned char*>::value, "Calling operator<<(CSHA512, const unsigned char*) is probably not what you want");
# 115 : 262850 : hasher.Write((const unsigned char*)&data, sizeof(data));
# 116 : 262850 : return hasher;
# 117 : 262850 : }
# 118 : :
# 119 : : #ifndef WIN32
# 120 : : void AddSockaddr(CSHA512& hasher, const struct sockaddr *addr)
# 121 : 27108 : {
# 122 [ + + ]: 27108 : if (addr == nullptr) return;
# 123 : 18072 : switch (addr->sa_family) {
# 124 [ + + ]: 9036 : case AF_INET:
# 125 : 9036 : hasher.Write((const unsigned char*)addr, sizeof(sockaddr_in));
# 126 : 9036 : break;
# 127 [ + + ]: 3765 : case AF_INET6:
# 128 : 3765 : hasher.Write((const unsigned char*)addr, sizeof(sockaddr_in6));
# 129 : 3765 : break;
# 130 [ + + ]: 5271 : default:
# 131 : 5271 : hasher.Write((const unsigned char*)&addr->sa_family, sizeof(addr->sa_family));
# 132 : 18072 : }
# 133 : 18072 : }
# 134 : :
# 135 : : void AddFile(CSHA512& hasher, const char *path)
# 136 : 4518 : {
# 137 : 4518 : struct stat sb = {};
# 138 : 4518 : int f = open(path, O_RDONLY);
# 139 : 4518 : size_t total = 0;
# 140 [ + + ]: 4518 : if (f != -1) {
# 141 : 3765 : unsigned char fbuf[4096];
# 142 : 3765 : int n;
# 143 : 3765 : hasher.Write((const unsigned char*)&f, sizeof(f));
# 144 [ + - ]: 3765 : if (fstat(f, &sb) == 0) hasher << sb;
# 145 : 4518 : do {
# 146 : 4518 : n = read(f, fbuf, sizeof(fbuf));
# 147 [ + - ]: 4518 : if (n > 0) hasher.Write(fbuf, n);
# 148 : 4518 : total += n;
# 149 : : /* not bothering with EINTR handling. */
# 150 [ + + ][ + - ]: 4518 : } while (n == sizeof(fbuf) && total < 1048576); // Read only the first 1 Mbyte
# 151 : 3765 : close(f);
# 152 : 3765 : }
# 153 : 4518 : }
# 154 : :
# 155 : : void AddPath(CSHA512& hasher, const char *path)
# 156 : 3765 : {
# 157 : 3765 : struct stat sb = {};
# 158 [ + - ]: 3765 : if (stat(path, &sb) == 0) {
# 159 : 3765 : hasher.Write((const unsigned char*)path, strlen(path) + 1);
# 160 : 3765 : hasher << sb;
# 161 : 3765 : }
# 162 : 3765 : }
# 163 : : #endif
# 164 : :
# 165 : : #if HAVE_SYSCTL
# 166 : : template<int... S>
# 167 : : void AddSysctl(CSHA512& hasher)
# 168 : 18752 : {
# 169 : 18752 : int CTL[sizeof...(S)] = {S...};
# 170 : 18752 : unsigned char buffer[65536];
# 171 : 18752 : size_t siz = 65536;
# 172 : 18752 : int ret = sysctl(CTL, sizeof...(S), buffer, &siz, nullptr, 0);
# 173 [ + - ][ + - ]: 18752 : if (ret == 0 || (ret == -1 && errno == ENOMEM)) {
# [ + - ][ + - ]
# [ + - ][ + - ]
# [ + - ][ + - ]
# [ + - ][ + - ]
# [ + - ][ + - ]
# [ + - ][ + - ]
# [ + - ][ - + ]
# [ + - ][ + - ]
# [ + - ][ + - ]
# [ - + ][ + - ]
# [ # # ][ # # ]
# [ + - ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ + - ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ - + ]
# [ # # ][ # # ]
# [ # # ][ + - ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# [ # # ][ # # ]
# 174 : 17863 : hasher << sizeof(CTL);
# 175 : 17863 : hasher.Write((const unsigned char*)CTL, sizeof(CTL));
# 176 [ - + ][ - + ]: 17863 : if (siz > sizeof(buffer)) siz = sizeof(buffer);
# [ - + ][ - + ]
# [ - + ][ - + ]
# [ - + ][ - + ]
# [ - + ][ - + ]
# [ - + ][ # # ]
# [ - + ][ - + ]
# [ - + ][ - + ]
# [ - + ][ - + ]
# [ - + ][ - + ]
# [ - + ][ - + ]
# 177 : 17863 : hasher << siz;
# 178 : 17863 : hasher.Write(buffer, siz);
# 179 : 17863 : }
# 180 : 18752 : }
# 181 : : #endif
# 182 : :
# 183 : : #ifdef HAVE_GETCPUID
# 184 : : void inline AddCPUID(CSHA512& hasher, uint32_t leaf, uint32_t subleaf, uint32_t& ax, uint32_t& bx, uint32_t& cx, uint32_t& dx)
# 185 : 32379 : {
# 186 : 32379 : GetCPUID(leaf, subleaf, ax, bx, cx, dx);
# 187 : 32379 : hasher << leaf << subleaf << ax << bx << cx << dx;
# 188 : 32379 : }
# 189 : :
# 190 : : void AddAllCPUID(CSHA512& hasher)
# 191 : 753 : {
# 192 : 753 : uint32_t ax, bx, cx, dx;
# 193 : : // Iterate over all standard leaves
# 194 : 753 : AddCPUID(hasher, 0, 0, ax, bx, cx, dx); // Returns max leaf in ax
# 195 : 753 : uint32_t max = ax;
# 196 [ + + ][ + - ]: 17319 : for (uint32_t leaf = 1; leaf <= max && leaf <= 0xFF; ++leaf) {
# 197 : 16566 : uint32_t maxsub = 0;
# 198 [ + - ]: 24849 : for (uint32_t subleaf = 0; subleaf <= 0xFF; ++subleaf) {
# 199 : 24849 : AddCPUID(hasher, leaf, subleaf, ax, bx, cx, dx);
# 200 : : // Iterate subleafs for leaf values 4, 7, 11, 13
# 201 [ + + ]: 24849 : if (leaf == 4) {
# 202 [ + + ]: 3765 : if ((ax & 0x1f) == 0) break;
# 203 [ + + ]: 21084 : } else if (leaf == 7) {
# 204 [ + - ]: 753 : if (subleaf == 0) maxsub = ax;
# 205 [ + - ]: 753 : if (subleaf == maxsub) break;
# 206 [ + + ]: 20331 : } else if (leaf == 11) {
# 207 [ + + ]: 2259 : if ((cx & 0xff00) == 0) break;
# 208 [ + + ]: 18072 : } else if (leaf == 13) {
# 209 [ + + ][ + - ]: 4518 : if (ax == 0 && bx == 0 && cx == 0 && dx == 0) break;
# [ + - ][ + - ]
# 210 : 13554 : } else {
# 211 : : // For any other leaf, stop after subleaf 0.
# 212 : 13554 : break;
# 213 : 13554 : }
# 214 : 24849 : }
# 215 : 16566 : }
# 216 : : // Iterate over all extended leaves
# 217 : 753 : AddCPUID(hasher, 0x80000000, 0, ax, bx, cx, dx); // Returns max extended leaf in ax
# 218 : 753 : uint32_t ext_max = ax;
# 219 [ + + ][ + - ]: 6777 : for (uint32_t leaf = 0x80000001; leaf <= ext_max && leaf <= 0x800000FF; ++leaf) {
# 220 : 6024 : AddCPUID(hasher, leaf, 0, ax, bx, cx, dx);
# 221 : 6024 : }
# 222 : 753 : }
# 223 : : #endif
# 224 : : } // namespace
# 225 : :
# 226 : : void RandAddDynamicEnv(CSHA512& hasher)
# 227 : 889 : {
# 228 : 889 : RandAddSeedPerfmon(hasher);
# 229 : :
# 230 : : // Various clocks
# 231 : : #ifdef WIN32
# 232 : : FILETIME ftime;
# 233 : : GetSystemTimeAsFileTime(&ftime);
# 234 : : hasher << ftime;
# 235 : : #else
# 236 : 889 : struct timespec ts = {};
# 237 : 889 : # ifdef CLOCK_MONOTONIC
# 238 : 889 : clock_gettime(CLOCK_MONOTONIC, &ts);
# 239 : 889 : hasher << ts;
# 240 : 889 : # endif
# 241 : 889 : # ifdef CLOCK_REALTIME
# 242 : 889 : clock_gettime(CLOCK_REALTIME, &ts);
# 243 : 889 : hasher << ts;
# 244 : 889 : # endif
# 245 : : # ifdef CLOCK_BOOTTIME
# 246 : : clock_gettime(CLOCK_BOOTTIME, &ts);
# 247 : : hasher << ts;
# 248 : : # endif
# 249 : : // gettimeofday is available on all UNIX systems, but only has microsecond precision.
# 250 : 889 : struct timeval tv = {};
# 251 : 889 : gettimeofday(&tv, nullptr);
# 252 : 889 : hasher << tv;
# 253 : 889 : #endif
# 254 : : // Probably redundant, but also use all the clocks C++11 provides:
# 255 : 889 : hasher << std::chrono::system_clock::now().time_since_epoch().count();
# 256 : 889 : hasher << std::chrono::steady_clock::now().time_since_epoch().count();
# 257 : 889 : hasher << std::chrono::high_resolution_clock::now().time_since_epoch().count();
# 258 : :
# 259 : 889 : #ifndef WIN32
# 260 : : // Current resource usage.
# 261 : 889 : struct rusage usage = {};
# 262 [ + - ]: 889 : if (getrusage(RUSAGE_SELF, &usage) == 0) hasher << usage;
# 263 : 889 : #endif
# 264 : :
# 265 : : #ifdef __linux__
# 266 : : AddFile(hasher, "/proc/diskstats");
# 267 : : AddFile(hasher, "/proc/vmstat");
# 268 : : AddFile(hasher, "/proc/schedstat");
# 269 : : AddFile(hasher, "/proc/zoneinfo");
# 270 : : AddFile(hasher, "/proc/meminfo");
# 271 : : AddFile(hasher, "/proc/softirqs");
# 272 : : AddFile(hasher, "/proc/stat");
# 273 : : AddFile(hasher, "/proc/self/schedstat");
# 274 : : AddFile(hasher, "/proc/self/status");
# 275 : : #endif
# 276 : :
# 277 : 889 : #if HAVE_SYSCTL
# 278 : 889 : # ifdef CTL_KERN
# 279 : 889 : # if defined(KERN_PROC) && defined(KERN_PROC_ALL)
# 280 : 889 : AddSysctl<CTL_KERN, KERN_PROC, KERN_PROC_ALL>(hasher);
# 281 : 889 : # endif
# 282 : 889 : # endif
# 283 : 889 : # ifdef CTL_HW
# 284 : 889 : # ifdef HW_DISKSTATS
# 285 : 889 : AddSysctl<CTL_HW, HW_DISKSTATS>(hasher);
# 286 : 889 : # endif
# 287 : 889 : # endif
# 288 : 889 : # ifdef CTL_VM
# 289 : 889 : # ifdef VM_LOADAVG
# 290 : 889 : AddSysctl<CTL_VM, VM_LOADAVG>(hasher);
# 291 : 889 : # endif
# 292 : 889 : # ifdef VM_TOTAL
# 293 : 889 : AddSysctl<CTL_VM, VM_TOTAL>(hasher);
# 294 : 889 : # endif
# 295 : 889 : # ifdef VM_METER
# 296 : 889 : AddSysctl<CTL_VM, VM_METER>(hasher);
# 297 : 889 : # endif
# 298 : 889 : # endif
# 299 : 889 : #endif
# 300 : :
# 301 : : // Stack and heap location
# 302 : 889 : void* addr = malloc(4097);
# 303 : 889 : hasher << &addr << addr;
# 304 : 889 : free(addr);
# 305 : 889 : }
# 306 : :
# 307 : : void RandAddStaticEnv(CSHA512& hasher)
# 308 : 753 : {
# 309 : : // Some compile-time static properties
# 310 : 753 : hasher << (CHAR_MIN < 0) << sizeof(void*) << sizeof(long) << sizeof(int);
# 311 : 753 : #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
# 312 : 753 : hasher << __GNUC__ << __GNUC_MINOR__ << __GNUC_PATCHLEVEL__;
# 313 : 753 : #endif
# 314 : : #ifdef _MSC_VER
# 315 : : hasher << _MSC_VER;
# 316 : : #endif
# 317 : 753 : hasher << __cplusplus;
# 318 : : #ifdef _XOPEN_VERSION
# 319 : : hasher << _XOPEN_VERSION;
# 320 : : #endif
# 321 : 753 : #ifdef __VERSION__
# 322 : 753 : const char* COMPILER_VERSION = __VERSION__;
# 323 : 753 : hasher.Write((const unsigned char*)COMPILER_VERSION, strlen(COMPILER_VERSION) + 1);
# 324 : 753 : #endif
# 325 : :
# 326 : : // Bitcoin client version
# 327 : 753 : hasher << CLIENT_VERSION;
# 328 : :
# 329 : : #if defined(HAVE_STRONG_GETAUXVAL) || defined(HAVE_WEAK_GETAUXVAL)
# 330 : : // Information available through getauxval()
# 331 : : # ifdef AT_HWCAP
# 332 : : hasher << getauxval(AT_HWCAP);
# 333 : : # endif
# 334 : : # ifdef AT_HWCAP2
# 335 : : hasher << getauxval(AT_HWCAP2);
# 336 : : # endif
# 337 : : # ifdef AT_RANDOM
# 338 : : const unsigned char* random_aux = (const unsigned char*)getauxval(AT_RANDOM);
# 339 : : if (random_aux) hasher.Write(random_aux, 16);
# 340 : : # endif
# 341 : : # ifdef AT_PLATFORM
# 342 : : const char* platform_str = (const char*)getauxval(AT_PLATFORM);
# 343 : : if (platform_str) hasher.Write((const unsigned char*)platform_str, strlen(platform_str) + 1);
# 344 : : # endif
# 345 : : # ifdef AT_EXECFN
# 346 : : const char* exec_str = (const char*)getauxval(AT_EXECFN);
# 347 : : if (exec_str) hasher.Write((const unsigned char*)exec_str, strlen(exec_str) + 1);
# 348 : : # endif
# 349 : : #endif // HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL
# 350 : :
# 351 : 753 : #ifdef HAVE_GETCPUID
# 352 : 753 : AddAllCPUID(hasher);
# 353 : 753 : #endif
# 354 : :
# 355 : : // Memory locations
# 356 : 753 : hasher << &hasher << &RandAddStaticEnv << &malloc << &errno << &environ;
# 357 : :
# 358 : : // Hostname
# 359 : 753 : char hname[256];
# 360 [ + - ]: 753 : if (gethostname(hname, 256) == 0) {
# 361 : 753 : hasher.Write((const unsigned char*)hname, strnlen(hname, 256));
# 362 : 753 : }
# 363 : :
# 364 : 753 : #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS
# 365 : : // Network interfaces
# 366 : 753 : struct ifaddrs *ifad = NULL;
# 367 : 753 : getifaddrs(&ifad);
# 368 : 753 : struct ifaddrs *ifit = ifad;
# 369 [ + + ]: 9789 : while (ifit != NULL) {
# 370 : 9036 : hasher.Write((const unsigned char*)&ifit, sizeof(ifit));
# 371 : 9036 : hasher.Write((const unsigned char*)ifit->ifa_name, strlen(ifit->ifa_name) + 1);
# 372 : 9036 : hasher.Write((const unsigned char*)&ifit->ifa_flags, sizeof(ifit->ifa_flags));
# 373 : 9036 : AddSockaddr(hasher, ifit->ifa_addr);
# 374 : 9036 : AddSockaddr(hasher, ifit->ifa_netmask);
# 375 : 9036 : AddSockaddr(hasher, ifit->ifa_dstaddr);
# 376 : 9036 : ifit = ifit->ifa_next;
# 377 : 9036 : }
# 378 : 753 : freeifaddrs(ifad);
# 379 : 753 : #endif
# 380 : :
# 381 : 753 : #ifndef WIN32
# 382 : : // UNIX kernel information
# 383 : 753 : struct utsname name;
# 384 [ + - ]: 753 : if (uname(&name) != -1) {
# 385 : 753 : hasher.Write((const unsigned char*)&name.sysname, strlen(name.sysname) + 1);
# 386 : 753 : hasher.Write((const unsigned char*)&name.nodename, strlen(name.nodename) + 1);
# 387 : 753 : hasher.Write((const unsigned char*)&name.release, strlen(name.release) + 1);
# 388 : 753 : hasher.Write((const unsigned char*)&name.version, strlen(name.version) + 1);
# 389 : 753 : hasher.Write((const unsigned char*)&name.machine, strlen(name.machine) + 1);
# 390 : 753 : }
# 391 : :
# 392 : : /* Path and filesystem provided data */
# 393 : 753 : AddPath(hasher, "/");
# 394 : 753 : AddPath(hasher, ".");
# 395 : 753 : AddPath(hasher, "/tmp");
# 396 : 753 : AddPath(hasher, "/home");
# 397 : 753 : AddPath(hasher, "/proc");
# 398 : : #ifdef __linux__
# 399 : : AddFile(hasher, "/proc/cmdline");
# 400 : : AddFile(hasher, "/proc/cpuinfo");
# 401 : : AddFile(hasher, "/proc/version");
# 402 : : #endif
# 403 : 753 : AddFile(hasher, "/etc/passwd");
# 404 : 753 : AddFile(hasher, "/etc/group");
# 405 : 753 : AddFile(hasher, "/etc/hosts");
# 406 : 753 : AddFile(hasher, "/etc/resolv.conf");
# 407 : 753 : AddFile(hasher, "/etc/timezone");
# 408 : 753 : AddFile(hasher, "/etc/localtime");
# 409 : 753 : #endif
# 410 : :
# 411 : : // For MacOS/BSDs, gather data through sysctl instead of /proc. Not all of these
# 412 : : // will exist on every system.
# 413 : 753 : #if HAVE_SYSCTL
# 414 : 753 : # ifdef CTL_HW
# 415 : 753 : # ifdef HW_MACHINE
# 416 : 753 : AddSysctl<CTL_HW, HW_MACHINE>(hasher);
# 417 : 753 : # endif
# 418 : 753 : # ifdef HW_MODEL
# 419 : 753 : AddSysctl<CTL_HW, HW_MODEL>(hasher);
# 420 : 753 : # endif
# 421 : 753 : # ifdef HW_NCPU
# 422 : 753 : AddSysctl<CTL_HW, HW_NCPU>(hasher);
# 423 : 753 : # endif
# 424 : 753 : # ifdef HW_PHYSMEM
# 425 : 753 : AddSysctl<CTL_HW, HW_PHYSMEM>(hasher);
# 426 : 753 : # endif
# 427 : 753 : # ifdef HW_USERMEM
# 428 : 753 : AddSysctl<CTL_HW, HW_USERMEM>(hasher);
# 429 : 753 : # endif
# 430 : 753 : # ifdef HW_MACHINE_ARCH
# 431 : 753 : AddSysctl<CTL_HW, HW_MACHINE_ARCH>(hasher);
# 432 : 753 : # endif
# 433 : 753 : # ifdef HW_REALMEM
# 434 : 753 : AddSysctl<CTL_HW, HW_REALMEM>(hasher);
# 435 : 753 : # endif
# 436 : : # ifdef HW_CPU_FREQ
# 437 : : AddSysctl<CTL_HW, HW_CPU_FREQ>(hasher);
# 438 : : # endif
# 439 : : # ifdef HW_BUS_FREQ
# 440 : : AddSysctl<CTL_HW, HW_BUS_FREQ>(hasher);
# 441 : : # endif
# 442 : : # ifdef HW_CACHELINE
# 443 : : AddSysctl<CTL_HW, HW_CACHELINE>(hasher);
# 444 : : # endif
# 445 : 753 : # endif
# 446 : 753 : # ifdef CTL_KERN
# 447 : 753 : # ifdef KERN_BOOTFILE
# 448 : 753 : AddSysctl<CTL_KERN, KERN_BOOTFILE>(hasher);
# 449 : 753 : # endif
# 450 : 753 : # ifdef KERN_BOOTTIME
# 451 : 753 : AddSysctl<CTL_KERN, KERN_BOOTTIME>(hasher);
# 452 : 753 : # endif
# 453 : 753 : # ifdef KERN_CLOCKRATE
# 454 : 753 : AddSysctl<CTL_KERN, KERN_CLOCKRATE>(hasher);
# 455 : 753 : # endif
# 456 : 753 : # ifdef KERN_HOSTID
# 457 : 753 : AddSysctl<CTL_KERN, KERN_HOSTID>(hasher);
# 458 : 753 : # endif
# 459 : 753 : # ifdef KERN_HOSTUUID
# 460 : 753 : AddSysctl<CTL_KERN, KERN_HOSTUUID>(hasher);
# 461 : 753 : # endif
# 462 : 753 : # ifdef KERN_HOSTNAME
# 463 : 753 : AddSysctl<CTL_KERN, KERN_HOSTNAME>(hasher);
# 464 : 753 : # endif
# 465 : 753 : # ifdef KERN_OSRELDATE
# 466 : 753 : AddSysctl<CTL_KERN, KERN_OSRELDATE>(hasher);
# 467 : 753 : # endif
# 468 : 753 : # ifdef KERN_OSRELEASE
# 469 : 753 : AddSysctl<CTL_KERN, KERN_OSRELEASE>(hasher);
# 470 : 753 : # endif
# 471 : 753 : # ifdef KERN_OSREV
# 472 : 753 : AddSysctl<CTL_KERN, KERN_OSREV>(hasher);
# 473 : 753 : # endif
# 474 : 753 : # ifdef KERN_OSTYPE
# 475 : 753 : AddSysctl<CTL_KERN, KERN_OSTYPE>(hasher);
# 476 : 753 : # endif
# 477 : 753 : # ifdef KERN_POSIX1
# 478 : 753 : AddSysctl<CTL_KERN, KERN_OSREV>(hasher);
# 479 : 753 : # endif
# 480 : 753 : # ifdef KERN_VERSION
# 481 : 753 : AddSysctl<CTL_KERN, KERN_VERSION>(hasher);
# 482 : 753 : # endif
# 483 : 753 : # endif
# 484 : 753 : #endif
# 485 : :
# 486 : : // Env variables
# 487 [ + - ]: 753 : if (environ) {
# 488 [ + + ]: 31624 : for (size_t i = 0; environ[i]; ++i) {
# 489 : 30871 : hasher.Write((const unsigned char*)environ[i], strlen(environ[i]));
# 490 : 30871 : }
# 491 : 753 : }
# 492 : :
# 493 : : // Process, thread, user, session, group, ... ids.
# 494 : : #ifdef WIN32
# 495 : : hasher << GetCurrentProcessId() << GetCurrentThreadId();
# 496 : : #else
# 497 : 753 : hasher << getpid() << getppid() << getsid(0) << getpgid(0) << getuid() << geteuid() << getgid() << getegid();
# 498 : 753 : #endif
# 499 : 753 : hasher << std::this_thread::get_id();
# 500 : 753 : }
|