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