1*0eefd307SCy Schubert /* $OpenBSD: getentropy_solaris.c,v 1.13 2018/11/20 08:04:28 deraadt Exp $ */ 2ff825849SDag-Erling Smørgrav 3ff825849SDag-Erling Smørgrav /* 4ff825849SDag-Erling Smørgrav * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org> 5ff825849SDag-Erling Smørgrav * Copyright (c) 2014 Bob Beck <beck@obtuse.com> 6ff825849SDag-Erling Smørgrav * 7ff825849SDag-Erling Smørgrav * Permission to use, copy, modify, and distribute this software for any 8ff825849SDag-Erling Smørgrav * purpose with or without fee is hereby granted, provided that the above 9ff825849SDag-Erling Smørgrav * copyright notice and this permission notice appear in all copies. 10ff825849SDag-Erling Smørgrav * 11ff825849SDag-Erling Smørgrav * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12ff825849SDag-Erling Smørgrav * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13ff825849SDag-Erling Smørgrav * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14ff825849SDag-Erling Smørgrav * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15ff825849SDag-Erling Smørgrav * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16ff825849SDag-Erling Smørgrav * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17ff825849SDag-Erling Smørgrav * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18*0eefd307SCy Schubert * 19*0eefd307SCy Schubert * Emulation of getentropy(2) as documented at: 20*0eefd307SCy Schubert * http://man.openbsd.org/getentropy.2 21ff825849SDag-Erling Smørgrav */ 22ff825849SDag-Erling Smørgrav 23*0eefd307SCy Schubert #include "config.h" 24ff825849SDag-Erling Smørgrav #include <sys/types.h> 25ff825849SDag-Erling Smørgrav #include <sys/param.h> 26ff825849SDag-Erling Smørgrav #include <sys/ioctl.h> 27ff825849SDag-Erling Smørgrav #include <sys/resource.h> 28ff825849SDag-Erling Smørgrav #include <sys/syscall.h> 29ff825849SDag-Erling Smørgrav #include <sys/statvfs.h> 30ff825849SDag-Erling Smørgrav #include <sys/socket.h> 31ff825849SDag-Erling Smørgrav #include <sys/mount.h> 32ff825849SDag-Erling Smørgrav #include <sys/mman.h> 33ff825849SDag-Erling Smørgrav #include <sys/stat.h> 34ff825849SDag-Erling Smørgrav #include <sys/time.h> 35ff825849SDag-Erling Smørgrav #include <stdlib.h> 3605ab2901SDag-Erling Smørgrav #ifdef HAVE_STDINT_H 37ff825849SDag-Erling Smørgrav #include <stdint.h> 3805ab2901SDag-Erling Smørgrav #endif 39ff825849SDag-Erling Smørgrav #include <stdio.h> 40*0eefd307SCy Schubert #include <link.h> 41ff825849SDag-Erling Smørgrav #include <termios.h> 42ff825849SDag-Erling Smørgrav #include <fcntl.h> 43ff825849SDag-Erling Smørgrav #include <signal.h> 44ff825849SDag-Erling Smørgrav #include <string.h> 45ff825849SDag-Erling Smørgrav #include <errno.h> 46ff825849SDag-Erling Smørgrav #include <unistd.h> 47ff825849SDag-Erling Smørgrav #include <time.h> 4805ab2901SDag-Erling Smørgrav #ifdef HAVE_SYS_SHA2_H 49ff825849SDag-Erling Smørgrav #include <sys/sha2.h> 50ff825849SDag-Erling Smørgrav #define SHA512_Init SHA512Init 51ff825849SDag-Erling Smørgrav #define SHA512_Update SHA512Update 52ff825849SDag-Erling Smørgrav #define SHA512_Final SHA512Final 5305ab2901SDag-Erling Smørgrav #else 5405ab2901SDag-Erling Smørgrav #include "openssl/sha.h" 5505ab2901SDag-Erling Smørgrav #endif 56ff825849SDag-Erling Smørgrav 57ff825849SDag-Erling Smørgrav #include <sys/vfs.h> 58ff825849SDag-Erling Smørgrav #include <sys/statfs.h> 59ff825849SDag-Erling Smørgrav #include <sys/loadavg.h> 60ff825849SDag-Erling Smørgrav 61ff825849SDag-Erling Smørgrav #define REPEAT 5 62ff825849SDag-Erling Smørgrav #define min(a, b) (((a) < (b)) ? (a) : (b)) 63ff825849SDag-Erling Smørgrav 64ff825849SDag-Erling Smørgrav #define HX(a, b) \ 65ff825849SDag-Erling Smørgrav do { \ 66ff825849SDag-Erling Smørgrav if ((a)) \ 67ff825849SDag-Erling Smørgrav HD(errno); \ 68ff825849SDag-Erling Smørgrav else \ 69ff825849SDag-Erling Smørgrav HD(b); \ 70ff825849SDag-Erling Smørgrav } while (0) 71ff825849SDag-Erling Smørgrav 72ff825849SDag-Erling Smørgrav #define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l))) 73ff825849SDag-Erling Smørgrav #define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x))) 74ff825849SDag-Erling Smørgrav #define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*))) 75ff825849SDag-Erling Smørgrav 76ff825849SDag-Erling Smørgrav int getentropy(void *buf, size_t len); 77ff825849SDag-Erling Smørgrav 78ff825849SDag-Erling Smørgrav static int getentropy_urandom(void *buf, size_t len, const char *path, 79ff825849SDag-Erling Smørgrav int devfscheck); 80ff825849SDag-Erling Smørgrav static int getentropy_fallback(void *buf, size_t len); 81*0eefd307SCy Schubert static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data); 82ff825849SDag-Erling Smørgrav 83ff825849SDag-Erling Smørgrav int 84ff825849SDag-Erling Smørgrav getentropy(void *buf, size_t len) 85ff825849SDag-Erling Smørgrav { 86ff825849SDag-Erling Smørgrav int ret = -1; 87ff825849SDag-Erling Smørgrav 88ff825849SDag-Erling Smørgrav if (len > 256) { 89ff825849SDag-Erling Smørgrav errno = EIO; 90*0eefd307SCy Schubert return (-1); 91ff825849SDag-Erling Smørgrav } 92ff825849SDag-Erling Smørgrav 93ff825849SDag-Erling Smørgrav /* 94ff825849SDag-Erling Smørgrav * Try to get entropy with /dev/urandom 95ff825849SDag-Erling Smørgrav * 96ff825849SDag-Erling Smørgrav * Solaris provides /dev/urandom as a symbolic link to 97ff825849SDag-Erling Smørgrav * /devices/pseudo/random@0:urandom which is provided by 98ff825849SDag-Erling Smørgrav * a devfs filesystem. Best practice is to use O_NOFOLLOW, 99ff825849SDag-Erling Smørgrav * so we must try the unpublished name directly. 100ff825849SDag-Erling Smørgrav * 101ff825849SDag-Erling Smørgrav * This can fail if the process is inside a chroot which lacks 102ff825849SDag-Erling Smørgrav * the devfs mount, or if file descriptors are exhausted. 103ff825849SDag-Erling Smørgrav */ 104ff825849SDag-Erling Smørgrav ret = getentropy_urandom(buf, len, 105ff825849SDag-Erling Smørgrav "/devices/pseudo/random@0:urandom", 1); 106ff825849SDag-Erling Smørgrav if (ret != -1) 107ff825849SDag-Erling Smørgrav return (ret); 108ff825849SDag-Erling Smørgrav 109ff825849SDag-Erling Smørgrav /* 110ff825849SDag-Erling Smørgrav * Unfortunately, chroot spaces on Solaris are sometimes setup 111ff825849SDag-Erling Smørgrav * with direct device node of the well-known /dev/urandom name 112ff825849SDag-Erling Smørgrav * (perhaps to avoid dragging all of devfs into the space). 113ff825849SDag-Erling Smørgrav * 114ff825849SDag-Erling Smørgrav * This can fail if the process is inside a chroot or if file 115ff825849SDag-Erling Smørgrav * descriptors are exhausted. 116ff825849SDag-Erling Smørgrav */ 117ff825849SDag-Erling Smørgrav ret = getentropy_urandom(buf, len, "/dev/urandom", 0); 118ff825849SDag-Erling Smørgrav if (ret != -1) 119ff825849SDag-Erling Smørgrav return (ret); 120ff825849SDag-Erling Smørgrav 121ff825849SDag-Erling Smørgrav /* 122ff825849SDag-Erling Smørgrav * Entropy collection via /dev/urandom has failed. 123ff825849SDag-Erling Smørgrav * 124ff825849SDag-Erling Smørgrav * No other API exists for collecting entropy, and we have 125ff825849SDag-Erling Smørgrav * no failsafe way to get it on Solaris that is not sensitive 126ff825849SDag-Erling Smørgrav * to resource exhaustion. 127ff825849SDag-Erling Smørgrav * 128ff825849SDag-Erling Smørgrav * We have very few options: 129ff825849SDag-Erling Smørgrav * - Even syslog_r is unsafe to call at this low level, so 130ff825849SDag-Erling Smørgrav * there is no way to alert the user or program. 131ff825849SDag-Erling Smørgrav * - Cannot call abort() because some systems have unsafe 132ff825849SDag-Erling Smørgrav * corefiles. 133ff825849SDag-Erling Smørgrav * - Could raise(SIGKILL) resulting in silent program termination. 134ff825849SDag-Erling Smørgrav * - Return EIO, to hint that arc4random's stir function 135ff825849SDag-Erling Smørgrav * should raise(SIGKILL) 136ff825849SDag-Erling Smørgrav * - Do the best under the circumstances.... 137ff825849SDag-Erling Smørgrav * 138ff825849SDag-Erling Smørgrav * This code path exists to bring light to the issue that Solaris 139ff825849SDag-Erling Smørgrav * does not provide a failsafe API for entropy collection. 140ff825849SDag-Erling Smørgrav * 141ff825849SDag-Erling Smørgrav * We hope this demonstrates that Solaris should consider 142ff825849SDag-Erling Smørgrav * providing a new failsafe API which works in a chroot or 143ff825849SDag-Erling Smørgrav * when file descriptors are exhausted. 144ff825849SDag-Erling Smørgrav */ 145ff825849SDag-Erling Smørgrav #undef FAIL_INSTEAD_OF_TRYING_FALLBACK 146ff825849SDag-Erling Smørgrav #ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK 147ff825849SDag-Erling Smørgrav raise(SIGKILL); 148ff825849SDag-Erling Smørgrav #endif 149ff825849SDag-Erling Smørgrav ret = getentropy_fallback(buf, len); 150ff825849SDag-Erling Smørgrav if (ret != -1) 151ff825849SDag-Erling Smørgrav return (ret); 152ff825849SDag-Erling Smørgrav 153ff825849SDag-Erling Smørgrav errno = EIO; 154ff825849SDag-Erling Smørgrav return (ret); 155ff825849SDag-Erling Smørgrav } 156ff825849SDag-Erling Smørgrav 157ff825849SDag-Erling Smørgrav static int 158ff825849SDag-Erling Smørgrav getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck) 159ff825849SDag-Erling Smørgrav { 160ff825849SDag-Erling Smørgrav struct stat st; 161ff825849SDag-Erling Smørgrav size_t i; 162ff825849SDag-Erling Smørgrav int fd, flags; 163ff825849SDag-Erling Smørgrav int save_errno = errno; 164ff825849SDag-Erling Smørgrav 165ff825849SDag-Erling Smørgrav start: 166ff825849SDag-Erling Smørgrav 167ff825849SDag-Erling Smørgrav flags = O_RDONLY; 168ff825849SDag-Erling Smørgrav #ifdef O_NOFOLLOW 169ff825849SDag-Erling Smørgrav flags |= O_NOFOLLOW; 170ff825849SDag-Erling Smørgrav #endif 171ff825849SDag-Erling Smørgrav #ifdef O_CLOEXEC 172ff825849SDag-Erling Smørgrav flags |= O_CLOEXEC; 173ff825849SDag-Erling Smørgrav #endif 174ff825849SDag-Erling Smørgrav fd = open(path, flags, 0); 175ff825849SDag-Erling Smørgrav if (fd == -1) { 176ff825849SDag-Erling Smørgrav if (errno == EINTR) 177ff825849SDag-Erling Smørgrav goto start; 178ff825849SDag-Erling Smørgrav goto nodevrandom; 179ff825849SDag-Erling Smørgrav } 180ff825849SDag-Erling Smørgrav #ifndef O_CLOEXEC 181ff825849SDag-Erling Smørgrav fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); 182ff825849SDag-Erling Smørgrav #endif 183ff825849SDag-Erling Smørgrav 184ff825849SDag-Erling Smørgrav /* Lightly verify that the device node looks sane */ 185ff825849SDag-Erling Smørgrav if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode) || 186ff825849SDag-Erling Smørgrav (devfscheck && (strcmp(st.st_fstype, "devfs") != 0))) { 187ff825849SDag-Erling Smørgrav close(fd); 188ff825849SDag-Erling Smørgrav goto nodevrandom; 189ff825849SDag-Erling Smørgrav } 190ff825849SDag-Erling Smørgrav for (i = 0; i < len; ) { 191ff825849SDag-Erling Smørgrav size_t wanted = len - i; 192ff825849SDag-Erling Smørgrav ssize_t ret = read(fd, (char *)buf + i, wanted); 193ff825849SDag-Erling Smørgrav 194ff825849SDag-Erling Smørgrav if (ret == -1) { 195ff825849SDag-Erling Smørgrav if (errno == EAGAIN || errno == EINTR) 196ff825849SDag-Erling Smørgrav continue; 197ff825849SDag-Erling Smørgrav close(fd); 198ff825849SDag-Erling Smørgrav goto nodevrandom; 199ff825849SDag-Erling Smørgrav } 200ff825849SDag-Erling Smørgrav i += ret; 201ff825849SDag-Erling Smørgrav } 202ff825849SDag-Erling Smørgrav close(fd); 203ff825849SDag-Erling Smørgrav errno = save_errno; 204*0eefd307SCy Schubert return (0); /* satisfied */ 205ff825849SDag-Erling Smørgrav nodevrandom: 206ff825849SDag-Erling Smørgrav errno = EIO; 207*0eefd307SCy Schubert return (-1); 208ff825849SDag-Erling Smørgrav } 209ff825849SDag-Erling Smørgrav 210ff825849SDag-Erling Smørgrav static const int cl[] = { 211ff825849SDag-Erling Smørgrav CLOCK_REALTIME, 212ff825849SDag-Erling Smørgrav #ifdef CLOCK_MONOTONIC 213ff825849SDag-Erling Smørgrav CLOCK_MONOTONIC, 214ff825849SDag-Erling Smørgrav #endif 215ff825849SDag-Erling Smørgrav #ifdef CLOCK_MONOTONIC_RAW 216ff825849SDag-Erling Smørgrav CLOCK_MONOTONIC_RAW, 217ff825849SDag-Erling Smørgrav #endif 218ff825849SDag-Erling Smørgrav #ifdef CLOCK_TAI 219ff825849SDag-Erling Smørgrav CLOCK_TAI, 220ff825849SDag-Erling Smørgrav #endif 221ff825849SDag-Erling Smørgrav #ifdef CLOCK_VIRTUAL 222ff825849SDag-Erling Smørgrav CLOCK_VIRTUAL, 223ff825849SDag-Erling Smørgrav #endif 224ff825849SDag-Erling Smørgrav #ifdef CLOCK_UPTIME 225ff825849SDag-Erling Smørgrav CLOCK_UPTIME, 226ff825849SDag-Erling Smørgrav #endif 227ff825849SDag-Erling Smørgrav #ifdef CLOCK_PROCESS_CPUTIME_ID 228ff825849SDag-Erling Smørgrav CLOCK_PROCESS_CPUTIME_ID, 229ff825849SDag-Erling Smørgrav #endif 230ff825849SDag-Erling Smørgrav #ifdef CLOCK_THREAD_CPUTIME_ID 231ff825849SDag-Erling Smørgrav CLOCK_THREAD_CPUTIME_ID, 232ff825849SDag-Erling Smørgrav #endif 233ff825849SDag-Erling Smørgrav }; 234ff825849SDag-Erling Smørgrav 235ff825849SDag-Erling Smørgrav static int 236*0eefd307SCy Schubert getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data) 237*0eefd307SCy Schubert { 238*0eefd307SCy Schubert SHA512_CTX *ctx = data; 239*0eefd307SCy Schubert 240*0eefd307SCy Schubert SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr)); 241*0eefd307SCy Schubert return (0); 242*0eefd307SCy Schubert } 243*0eefd307SCy Schubert 244*0eefd307SCy Schubert static int 245ff825849SDag-Erling Smørgrav getentropy_fallback(void *buf, size_t len) 246ff825849SDag-Erling Smørgrav { 247ff825849SDag-Erling Smørgrav uint8_t results[SHA512_DIGEST_LENGTH]; 248ff825849SDag-Erling Smørgrav int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat; 249ff825849SDag-Erling Smørgrav static int cnt; 250ff825849SDag-Erling Smørgrav struct timespec ts; 251ff825849SDag-Erling Smørgrav struct timeval tv; 252ff825849SDag-Erling Smørgrav double loadavg[3]; 253ff825849SDag-Erling Smørgrav struct rusage ru; 254ff825849SDag-Erling Smørgrav sigset_t sigset; 255ff825849SDag-Erling Smørgrav struct stat st; 256ff825849SDag-Erling Smørgrav SHA512_CTX ctx; 257ff825849SDag-Erling Smørgrav static pid_t lastpid; 258ff825849SDag-Erling Smørgrav pid_t pid; 259ff825849SDag-Erling Smørgrav size_t i, ii, m; 260ff825849SDag-Erling Smørgrav char *p; 261ff825849SDag-Erling Smørgrav 262ff825849SDag-Erling Smørgrav pid = getpid(); 263ff825849SDag-Erling Smørgrav if (lastpid == pid) { 264ff825849SDag-Erling Smørgrav faster = 1; 265ff825849SDag-Erling Smørgrav repeat = 2; 266ff825849SDag-Erling Smørgrav } else { 267ff825849SDag-Erling Smørgrav faster = 0; 268ff825849SDag-Erling Smørgrav lastpid = pid; 269ff825849SDag-Erling Smørgrav repeat = REPEAT; 270ff825849SDag-Erling Smørgrav } 271ff825849SDag-Erling Smørgrav for (i = 0; i < len; ) { 272ff825849SDag-Erling Smørgrav int j; 273ff825849SDag-Erling Smørgrav SHA512_Init(&ctx); 274ff825849SDag-Erling Smørgrav for (j = 0; j < repeat; j++) { 275ff825849SDag-Erling Smørgrav HX((e = gettimeofday(&tv, NULL)) == -1, tv); 276ff825849SDag-Erling Smørgrav if (e != -1) { 277ff825849SDag-Erling Smørgrav cnt += (int)tv.tv_sec; 278ff825849SDag-Erling Smørgrav cnt += (int)tv.tv_usec; 279ff825849SDag-Erling Smørgrav } 280ff825849SDag-Erling Smørgrav 281*0eefd307SCy Schubert dl_iterate_phdr(getentropy_phdr, &ctx); 282*0eefd307SCy Schubert 283ff825849SDag-Erling Smørgrav for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) 284ff825849SDag-Erling Smørgrav HX(clock_gettime(cl[ii], &ts) == -1, ts); 285ff825849SDag-Erling Smørgrav 286ff825849SDag-Erling Smørgrav HX((pid = getpid()) == -1, pid); 287ff825849SDag-Erling Smørgrav HX((pid = getsid(pid)) == -1, pid); 288ff825849SDag-Erling Smørgrav HX((pid = getppid()) == -1, pid); 289ff825849SDag-Erling Smørgrav HX((pid = getpgid(0)) == -1, pid); 290ff825849SDag-Erling Smørgrav HX((e = getpriority(0, 0)) == -1, e); 291ff825849SDag-Erling Smørgrav HX((getloadavg(loadavg, 3) == -1), loadavg); 292ff825849SDag-Erling Smørgrav 293ff825849SDag-Erling Smørgrav if (!faster) { 294ff825849SDag-Erling Smørgrav ts.tv_sec = 0; 295ff825849SDag-Erling Smørgrav ts.tv_nsec = 1; 296ff825849SDag-Erling Smørgrav (void) nanosleep(&ts, NULL); 297ff825849SDag-Erling Smørgrav } 298ff825849SDag-Erling Smørgrav 299ff825849SDag-Erling Smørgrav HX(sigpending(&sigset) == -1, sigset); 300ff825849SDag-Erling Smørgrav HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, 301ff825849SDag-Erling Smørgrav sigset); 302ff825849SDag-Erling Smørgrav 303ff825849SDag-Erling Smørgrav HF(getentropy); /* an addr in this library */ 304ff825849SDag-Erling Smørgrav HF(printf); /* an addr in libc */ 305ff825849SDag-Erling Smørgrav p = (char *)&p; 306ff825849SDag-Erling Smørgrav HD(p); /* an addr on stack */ 307ff825849SDag-Erling Smørgrav p = (char *)&errno; 308ff825849SDag-Erling Smørgrav HD(p); /* the addr of errno */ 309ff825849SDag-Erling Smørgrav 310ff825849SDag-Erling Smørgrav if (i == 0) { 311ff825849SDag-Erling Smørgrav struct sockaddr_storage ss; 312ff825849SDag-Erling Smørgrav struct statvfs stvfs; 313ff825849SDag-Erling Smørgrav struct termios tios; 314ff825849SDag-Erling Smørgrav socklen_t ssl; 315ff825849SDag-Erling Smørgrav off_t off; 316ff825849SDag-Erling Smørgrav 317ff825849SDag-Erling Smørgrav /* 318ff825849SDag-Erling Smørgrav * Prime-sized mappings encourage fragmentation; 319ff825849SDag-Erling Smørgrav * thus exposing some address entropy. 320ff825849SDag-Erling Smørgrav */ 321ff825849SDag-Erling Smørgrav struct mm { 322ff825849SDag-Erling Smørgrav size_t npg; 323ff825849SDag-Erling Smørgrav void *p; 324ff825849SDag-Erling Smørgrav } mm[] = { 325ff825849SDag-Erling Smørgrav { 17, MAP_FAILED }, { 3, MAP_FAILED }, 326ff825849SDag-Erling Smørgrav { 11, MAP_FAILED }, { 2, MAP_FAILED }, 327ff825849SDag-Erling Smørgrav { 5, MAP_FAILED }, { 3, MAP_FAILED }, 328ff825849SDag-Erling Smørgrav { 7, MAP_FAILED }, { 1, MAP_FAILED }, 329ff825849SDag-Erling Smørgrav { 57, MAP_FAILED }, { 3, MAP_FAILED }, 330ff825849SDag-Erling Smørgrav { 131, MAP_FAILED }, { 1, MAP_FAILED }, 331ff825849SDag-Erling Smørgrav }; 332ff825849SDag-Erling Smørgrav 333ff825849SDag-Erling Smørgrav for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { 334ff825849SDag-Erling Smørgrav HX(mm[m].p = mmap(NULL, 335ff825849SDag-Erling Smørgrav mm[m].npg * pgs, 336ff825849SDag-Erling Smørgrav PROT_READ|PROT_WRITE, 337ff825849SDag-Erling Smørgrav MAP_PRIVATE|MAP_ANON, -1, 338ff825849SDag-Erling Smørgrav (off_t)0), mm[m].p); 339ff825849SDag-Erling Smørgrav if (mm[m].p != MAP_FAILED) { 340ff825849SDag-Erling Smørgrav size_t mo; 341ff825849SDag-Erling Smørgrav 342ff825849SDag-Erling Smørgrav /* Touch some memory... */ 343ff825849SDag-Erling Smørgrav p = mm[m].p; 344ff825849SDag-Erling Smørgrav mo = cnt % 345ff825849SDag-Erling Smørgrav (mm[m].npg * pgs - 1); 346ff825849SDag-Erling Smørgrav p[mo] = 1; 347ff825849SDag-Erling Smørgrav cnt += (int)((long)(mm[m].p) 348ff825849SDag-Erling Smørgrav / pgs); 349ff825849SDag-Erling Smørgrav } 350ff825849SDag-Erling Smørgrav 351ff825849SDag-Erling Smørgrav /* Check cnts and times... */ 352ff825849SDag-Erling Smørgrav for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); 353ff825849SDag-Erling Smørgrav ii++) { 354ff825849SDag-Erling Smørgrav HX((e = clock_gettime(cl[ii], 355ff825849SDag-Erling Smørgrav &ts)) == -1, ts); 356ff825849SDag-Erling Smørgrav if (e != -1) 357ff825849SDag-Erling Smørgrav cnt += (int)ts.tv_nsec; 358ff825849SDag-Erling Smørgrav } 359ff825849SDag-Erling Smørgrav 360ff825849SDag-Erling Smørgrav HX((e = getrusage(RUSAGE_SELF, 361ff825849SDag-Erling Smørgrav &ru)) == -1, ru); 362ff825849SDag-Erling Smørgrav if (e != -1) { 363ff825849SDag-Erling Smørgrav cnt += (int)ru.ru_utime.tv_sec; 364ff825849SDag-Erling Smørgrav cnt += (int)ru.ru_utime.tv_usec; 365ff825849SDag-Erling Smørgrav } 366ff825849SDag-Erling Smørgrav } 367ff825849SDag-Erling Smørgrav 368ff825849SDag-Erling Smørgrav for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { 369ff825849SDag-Erling Smørgrav if (mm[m].p != MAP_FAILED) 370ff825849SDag-Erling Smørgrav munmap(mm[m].p, mm[m].npg * pgs); 371ff825849SDag-Erling Smørgrav mm[m].p = MAP_FAILED; 372ff825849SDag-Erling Smørgrav } 373ff825849SDag-Erling Smørgrav 374ff825849SDag-Erling Smørgrav HX(stat(".", &st) == -1, st); 375ff825849SDag-Erling Smørgrav HX(statvfs(".", &stvfs) == -1, stvfs); 376ff825849SDag-Erling Smørgrav 377ff825849SDag-Erling Smørgrav HX(stat("/", &st) == -1, st); 378ff825849SDag-Erling Smørgrav HX(statvfs("/", &stvfs) == -1, stvfs); 379ff825849SDag-Erling Smørgrav 380ff825849SDag-Erling Smørgrav HX((e = fstat(0, &st)) == -1, st); 381ff825849SDag-Erling Smørgrav if (e == -1) { 382ff825849SDag-Erling Smørgrav if (S_ISREG(st.st_mode) || 383ff825849SDag-Erling Smørgrav S_ISFIFO(st.st_mode) || 384ff825849SDag-Erling Smørgrav S_ISSOCK(st.st_mode)) { 385ff825849SDag-Erling Smørgrav HX(fstatvfs(0, &stvfs) == -1, 386ff825849SDag-Erling Smørgrav stvfs); 387ff825849SDag-Erling Smørgrav HX((off = lseek(0, (off_t)0, 388ff825849SDag-Erling Smørgrav SEEK_CUR)) < 0, off); 389ff825849SDag-Erling Smørgrav } 390ff825849SDag-Erling Smørgrav if (S_ISCHR(st.st_mode)) { 391ff825849SDag-Erling Smørgrav HX(tcgetattr(0, &tios) == -1, 392ff825849SDag-Erling Smørgrav tios); 393ff825849SDag-Erling Smørgrav } else if (S_ISSOCK(st.st_mode)) { 394ff825849SDag-Erling Smørgrav memset(&ss, 0, sizeof ss); 395ff825849SDag-Erling Smørgrav ssl = sizeof(ss); 396ff825849SDag-Erling Smørgrav HX(getpeername(0, 397ff825849SDag-Erling Smørgrav (void *)&ss, &ssl) == -1, 398ff825849SDag-Erling Smørgrav ss); 399ff825849SDag-Erling Smørgrav } 400ff825849SDag-Erling Smørgrav } 401ff825849SDag-Erling Smørgrav 402ff825849SDag-Erling Smørgrav HX((e = getrusage(RUSAGE_CHILDREN, 403ff825849SDag-Erling Smørgrav &ru)) == -1, ru); 404ff825849SDag-Erling Smørgrav if (e != -1) { 405ff825849SDag-Erling Smørgrav cnt += (int)ru.ru_utime.tv_sec; 406ff825849SDag-Erling Smørgrav cnt += (int)ru.ru_utime.tv_usec; 407ff825849SDag-Erling Smørgrav } 408ff825849SDag-Erling Smørgrav } else { 409ff825849SDag-Erling Smørgrav /* Subsequent hashes absorb previous result */ 410ff825849SDag-Erling Smørgrav HD(results); 411ff825849SDag-Erling Smørgrav } 412ff825849SDag-Erling Smørgrav 413ff825849SDag-Erling Smørgrav HX((e = gettimeofday(&tv, NULL)) == -1, tv); 414ff825849SDag-Erling Smørgrav if (e != -1) { 415ff825849SDag-Erling Smørgrav cnt += (int)tv.tv_sec; 416ff825849SDag-Erling Smørgrav cnt += (int)tv.tv_usec; 417ff825849SDag-Erling Smørgrav } 418ff825849SDag-Erling Smørgrav 419ff825849SDag-Erling Smørgrav HD(cnt); 420ff825849SDag-Erling Smørgrav } 421ff825849SDag-Erling Smørgrav SHA512_Final(results, &ctx); 422ff825849SDag-Erling Smørgrav memcpy((char *)buf + i, results, min(sizeof(results), len - i)); 423ff825849SDag-Erling Smørgrav i += min(sizeof(results), len - i); 424ff825849SDag-Erling Smørgrav } 425*0eefd307SCy Schubert explicit_bzero(&ctx, sizeof ctx); 426*0eefd307SCy Schubert explicit_bzero(results, sizeof results); 427ff825849SDag-Erling Smørgrav errno = save_errno; 428*0eefd307SCy Schubert return (0); /* satisfied */ 429ff825849SDag-Erling Smørgrav } 430