Source code pulled from OpenBSD for OpenNTPD. The place to contribute to this code is via the OpenBSD CVS tree.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

525 lines
12 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. /* $OpenBSD: getentropy_linux.c,v 1.45.4.1 2018/12/15 15:10:12 bcook Exp $ */
  2. /*
  3. * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
  4. * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. *
  18. * Emulation of getentropy(2) as documented at:
  19. * http://man.openbsd.org/getentropy.2
  20. */
  21. #define _POSIX_C_SOURCE 199309L
  22. #define _GNU_SOURCE 1
  23. #include <sys/types.h>
  24. #include <sys/param.h>
  25. #include <sys/ioctl.h>
  26. #include <sys/resource.h>
  27. #include <sys/syscall.h>
  28. #ifdef SYS__sysctl
  29. #include <linux/sysctl.h>
  30. #endif
  31. #include <sys/statvfs.h>
  32. #include <sys/socket.h>
  33. #include <sys/mount.h>
  34. #include <sys/mman.h>
  35. #include <sys/stat.h>
  36. #include <sys/time.h>
  37. #include <stdlib.h>
  38. #include <stdint.h>
  39. #include <stdio.h>
  40. #include <link.h>
  41. #include <termios.h>
  42. #include <fcntl.h>
  43. #include <signal.h>
  44. #include <string.h>
  45. #include <errno.h>
  46. #include <unistd.h>
  47. #include <time.h>
  48. #include <openssl/sha.h>
  49. #include <linux/types.h>
  50. #include <linux/random.h>
  51. #ifdef HAVE_GETAUXVAL
  52. #include <sys/auxv.h>
  53. #endif
  54. #include <sys/vfs.h>
  55. #define REPEAT 5
  56. #define min(a, b) (((a) < (b)) ? (a) : (b))
  57. #define HX(a, b) \
  58. do { \
  59. if ((a)) \
  60. HD(errno); \
  61. else \
  62. HD(b); \
  63. } while (0)
  64. #define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
  65. #define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
  66. #define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
  67. int getentropy(void *buf, size_t len);
  68. #if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
  69. static int getentropy_getrandom(void *buf, size_t len);
  70. #endif
  71. static int getentropy_urandom(void *buf, size_t len);
  72. #ifdef SYS__sysctl
  73. static int getentropy_sysctl(void *buf, size_t len);
  74. #endif
  75. static int getentropy_fallback(void *buf, size_t len);
  76. static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
  77. int
  78. getentropy(void *buf, size_t len)
  79. {
  80. int ret = -1;
  81. if (len > 256) {
  82. errno = EIO;
  83. return (-1);
  84. }
  85. #if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
  86. /*
  87. * Try descriptor-less getrandom(), in non-blocking mode.
  88. *
  89. * The design of Linux getrandom is broken. It has an
  90. * uninitialized phase coupled with blocking behaviour, which
  91. * is unacceptable from within a library at boot time without
  92. * possible recovery. See http://bugs.python.org/issue26839#msg267745
  93. */
  94. ret = getentropy_getrandom(buf, len);
  95. if (ret != -1)
  96. return (ret);
  97. #endif
  98. /*
  99. * Try to get entropy with /dev/urandom
  100. *
  101. * This can fail if the process is inside a chroot or if file
  102. * descriptors are exhausted.
  103. */
  104. ret = getentropy_urandom(buf, len);
  105. if (ret != -1)
  106. return (ret);
  107. #ifdef SYS__sysctl
  108. /*
  109. * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
  110. * sysctl is a failsafe API, so it guarantees a result. This
  111. * should work inside a chroot, or when file descriptors are
  112. * exhausted.
  113. *
  114. * However this can fail if the Linux kernel removes support
  115. * for sysctl. Starting in 2007, there have been efforts to
  116. * deprecate the sysctl API/ABI, and push callers towards use
  117. * of the chroot-unavailable fd-using /proc mechanism --
  118. * essentially the same problems as /dev/urandom.
  119. *
  120. * Numerous setbacks have been encountered in their deprecation
  121. * schedule, so as of June 2014 the kernel ABI still exists on
  122. * most Linux architectures. The sysctl() stub in libc is missing
  123. * on some systems. There are also reports that some kernels
  124. * spew messages to the console.
  125. */
  126. ret = getentropy_sysctl(buf, len);
  127. if (ret != -1)
  128. return (ret);
  129. #endif /* SYS__sysctl */
  130. /*
  131. * Entropy collection via /dev/urandom and sysctl have failed.
  132. *
  133. * No other API exists for collecting entropy. See the large
  134. * comment block above.
  135. *
  136. * We have very few options:
  137. * - Even syslog_r is unsafe to call at this low level, so
  138. * there is no way to alert the user or program.
  139. * - Cannot call abort() because some systems have unsafe
  140. * corefiles.
  141. * - Could raise(SIGKILL) resulting in silent program termination.
  142. * - Return EIO, to hint that arc4random's stir function
  143. * should raise(SIGKILL)
  144. * - Do the best under the circumstances....
  145. *
  146. * This code path exists to bring light to the issue that Linux
  147. * still does not provide a failsafe API for entropy collection.
  148. *
  149. * We hope this demonstrates that Linux should either retain their
  150. * sysctl ABI, or consider providing a new failsafe API which
  151. * works in a chroot or when file descriptors are exhausted.
  152. */
  153. #undef FAIL_INSTEAD_OF_TRYING_FALLBACK
  154. #ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
  155. raise(SIGKILL);
  156. #endif
  157. ret = getentropy_fallback(buf, len);
  158. if (ret != -1)
  159. return (ret);
  160. errno = EIO;
  161. return (ret);
  162. }
  163. #if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
  164. static int
  165. getentropy_getrandom(void *buf, size_t len)
  166. {
  167. int pre_errno = errno;
  168. int ret;
  169. if (len > 256)
  170. return (-1);
  171. do {
  172. ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
  173. } while (ret == -1 && errno == EINTR);
  174. if (ret != len)
  175. return (-1);
  176. errno = pre_errno;
  177. return (0);
  178. }
  179. #endif
  180. static int
  181. getentropy_urandom(void *buf, size_t len)
  182. {
  183. struct stat st;
  184. size_t i;
  185. int fd, cnt, flags;
  186. int save_errno = errno;
  187. start:
  188. flags = O_RDONLY;
  189. #ifdef O_NOFOLLOW
  190. flags |= O_NOFOLLOW;
  191. #endif
  192. #ifdef O_CLOEXEC
  193. flags |= O_CLOEXEC;
  194. #endif
  195. fd = open("/dev/urandom", flags, 0);
  196. if (fd == -1) {
  197. if (errno == EINTR)
  198. goto start;
  199. goto nodevrandom;
  200. }
  201. #ifndef O_CLOEXEC
  202. fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
  203. #endif
  204. /* Lightly verify that the device node looks sane */
  205. if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
  206. close(fd);
  207. goto nodevrandom;
  208. }
  209. if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
  210. close(fd);
  211. goto nodevrandom;
  212. }
  213. for (i = 0; i < len; ) {
  214. size_t wanted = len - i;
  215. ssize_t ret = read(fd, (char *)buf + i, wanted);
  216. if (ret == -1) {
  217. if (errno == EAGAIN || errno == EINTR)
  218. continue;
  219. close(fd);
  220. goto nodevrandom;
  221. }
  222. i += ret;
  223. }
  224. close(fd);
  225. errno = save_errno;
  226. return (0); /* satisfied */
  227. nodevrandom:
  228. errno = EIO;
  229. return (-1);
  230. }
  231. #ifdef SYS__sysctl
  232. static int
  233. getentropy_sysctl(void *buf, size_t len)
  234. {
  235. static int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
  236. size_t i;
  237. int save_errno = errno;
  238. for (i = 0; i < len; ) {
  239. size_t chunk = min(len - i, 16);
  240. /* SYS__sysctl because some systems already removed sysctl() */
  241. struct __sysctl_args args = {
  242. .name = mib,
  243. .nlen = 3,
  244. .oldval = (char *)buf + i,
  245. .oldlenp = &chunk,
  246. };
  247. if (syscall(SYS__sysctl, &args) != 0)
  248. goto sysctlfailed;
  249. i += chunk;
  250. }
  251. errno = save_errno;
  252. return (0); /* satisfied */
  253. sysctlfailed:
  254. errno = EIO;
  255. return (-1);
  256. }
  257. #endif /* SYS__sysctl */
  258. static const int cl[] = {
  259. CLOCK_REALTIME,
  260. #ifdef CLOCK_MONOTONIC
  261. CLOCK_MONOTONIC,
  262. #endif
  263. #ifdef CLOCK_MONOTONIC_RAW
  264. CLOCK_MONOTONIC_RAW,
  265. #endif
  266. #ifdef CLOCK_TAI
  267. CLOCK_TAI,
  268. #endif
  269. #ifdef CLOCK_VIRTUAL
  270. CLOCK_VIRTUAL,
  271. #endif
  272. #ifdef CLOCK_UPTIME
  273. CLOCK_UPTIME,
  274. #endif
  275. #ifdef CLOCK_PROCESS_CPUTIME_ID
  276. CLOCK_PROCESS_CPUTIME_ID,
  277. #endif
  278. #ifdef CLOCK_THREAD_CPUTIME_ID
  279. CLOCK_THREAD_CPUTIME_ID,
  280. #endif
  281. };
  282. static int
  283. getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
  284. {
  285. SHA512_CTX *ctx = data;
  286. SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
  287. return (0);
  288. }
  289. static int
  290. getentropy_fallback(void *buf, size_t len)
  291. {
  292. uint8_t results[SHA512_DIGEST_LENGTH];
  293. int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
  294. static int cnt;
  295. struct timespec ts;
  296. struct timeval tv;
  297. struct rusage ru;
  298. sigset_t sigset;
  299. struct stat st;
  300. SHA512_CTX ctx;
  301. static pid_t lastpid;
  302. pid_t pid;
  303. size_t i, ii, m;
  304. char *p;
  305. pid = getpid();
  306. if (lastpid == pid) {
  307. faster = 1;
  308. repeat = 2;
  309. } else {
  310. faster = 0;
  311. lastpid = pid;
  312. repeat = REPEAT;
  313. }
  314. for (i = 0; i < len; ) {
  315. int j;
  316. SHA512_Init(&ctx);
  317. for (j = 0; j < repeat; j++) {
  318. HX((e = gettimeofday(&tv, NULL)) == -1, tv);
  319. if (e != -1) {
  320. cnt += (int)tv.tv_sec;
  321. cnt += (int)tv.tv_usec;
  322. }
  323. dl_iterate_phdr(getentropy_phdr, &ctx);
  324. for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
  325. HX(clock_gettime(cl[ii], &ts) == -1, ts);
  326. HX((pid = getpid()) == -1, pid);
  327. HX((pid = getsid(pid)) == -1, pid);
  328. HX((pid = getppid()) == -1, pid);
  329. HX((pid = getpgid(0)) == -1, pid);
  330. HX((e = getpriority(0, 0)) == -1, e);
  331. if (!faster) {
  332. ts.tv_sec = 0;
  333. ts.tv_nsec = 1;
  334. (void) nanosleep(&ts, NULL);
  335. }
  336. HX(sigpending(&sigset) == -1, sigset);
  337. HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
  338. sigset);
  339. HF(getentropy); /* an addr in this library */
  340. HF(printf); /* an addr in libc */
  341. p = (char *)&p;
  342. HD(p); /* an addr on stack */
  343. p = (char *)&errno;
  344. HD(p); /* the addr of errno */
  345. if (i == 0) {
  346. struct sockaddr_storage ss;
  347. struct statvfs stvfs;
  348. struct termios tios;
  349. struct statfs stfs;
  350. socklen_t ssl;
  351. off_t off;
  352. /*
  353. * Prime-sized mappings encourage fragmentation;
  354. * thus exposing some address entropy.
  355. */
  356. struct mm {
  357. size_t npg;
  358. void *p;
  359. } mm[] = {
  360. { 17, MAP_FAILED }, { 3, MAP_FAILED },
  361. { 11, MAP_FAILED }, { 2, MAP_FAILED },
  362. { 5, MAP_FAILED }, { 3, MAP_FAILED },
  363. { 7, MAP_FAILED }, { 1, MAP_FAILED },
  364. { 57, MAP_FAILED }, { 3, MAP_FAILED },
  365. { 131, MAP_FAILED }, { 1, MAP_FAILED },
  366. };
  367. for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
  368. HX(mm[m].p = mmap(NULL,
  369. mm[m].npg * pgs,
  370. PROT_READ|PROT_WRITE,
  371. MAP_PRIVATE|MAP_ANON, -1,
  372. (off_t)0), mm[m].p);
  373. if (mm[m].p != MAP_FAILED) {
  374. size_t mo;
  375. /* Touch some memory... */
  376. p = mm[m].p;
  377. mo = cnt %
  378. (mm[m].npg * pgs - 1);
  379. p[mo] = 1;
  380. cnt += (int)((long)(mm[m].p)
  381. / pgs);
  382. }
  383. /* Check cnts and times... */
  384. for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
  385. ii++) {
  386. HX((e = clock_gettime(cl[ii],
  387. &ts)) == -1, ts);
  388. if (e != -1)
  389. cnt += (int)ts.tv_nsec;
  390. }
  391. HX((e = getrusage(RUSAGE_SELF,
  392. &ru)) == -1, ru);
  393. if (e != -1) {
  394. cnt += (int)ru.ru_utime.tv_sec;
  395. cnt += (int)ru.ru_utime.tv_usec;
  396. }
  397. }
  398. for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
  399. if (mm[m].p != MAP_FAILED)
  400. munmap(mm[m].p, mm[m].npg * pgs);
  401. mm[m].p = MAP_FAILED;
  402. }
  403. HX(stat(".", &st) == -1, st);
  404. HX(statvfs(".", &stvfs) == -1, stvfs);
  405. HX(statfs(".", &stfs) == -1, stfs);
  406. HX(stat("/", &st) == -1, st);
  407. HX(statvfs("/", &stvfs) == -1, stvfs);
  408. HX(statfs("/", &stfs) == -1, stfs);
  409. HX((e = fstat(0, &st)) == -1, st);
  410. if (e == -1) {
  411. if (S_ISREG(st.st_mode) ||
  412. S_ISFIFO(st.st_mode) ||
  413. S_ISSOCK(st.st_mode)) {
  414. HX(fstatvfs(0, &stvfs) == -1,
  415. stvfs);
  416. HX(fstatfs(0, &stfs) == -1,
  417. stfs);
  418. HX((off = lseek(0, (off_t)0,
  419. SEEK_CUR)) < 0, off);
  420. }
  421. if (S_ISCHR(st.st_mode)) {
  422. HX(tcgetattr(0, &tios) == -1,
  423. tios);
  424. } else if (S_ISSOCK(st.st_mode)) {
  425. memset(&ss, 0, sizeof ss);
  426. ssl = sizeof(ss);
  427. HX(getpeername(0,
  428. (void *)&ss, &ssl) == -1,
  429. ss);
  430. }
  431. }
  432. HX((e = getrusage(RUSAGE_CHILDREN,
  433. &ru)) == -1, ru);
  434. if (e != -1) {
  435. cnt += (int)ru.ru_utime.tv_sec;
  436. cnt += (int)ru.ru_utime.tv_usec;
  437. }
  438. } else {
  439. /* Subsequent hashes absorb previous result */
  440. HD(results);
  441. }
  442. HX((e = gettimeofday(&tv, NULL)) == -1, tv);
  443. if (e != -1) {
  444. cnt += (int)tv.tv_sec;
  445. cnt += (int)tv.tv_usec;
  446. }
  447. HD(cnt);
  448. }
  449. #ifdef HAVE_GETAUXVAL
  450. #ifdef AT_RANDOM
  451. /* Not as random as you think but we take what we are given */
  452. p = (char *) getauxval(AT_RANDOM);
  453. if (p)
  454. HR(p, 16);
  455. #endif
  456. #ifdef AT_SYSINFO_EHDR
  457. p = (char *) getauxval(AT_SYSINFO_EHDR);
  458. if (p)
  459. HR(p, pgs);
  460. #endif
  461. #ifdef AT_BASE
  462. p = (char *) getauxval(AT_BASE);
  463. if (p)
  464. HD(p);
  465. #endif
  466. #endif
  467. SHA512_Final(results, &ctx);
  468. memcpy((char *)buf + i, results, min(sizeof(results), len - i));
  469. i += min(sizeof(results), len - i);
  470. }
  471. explicit_bzero(&ctx, sizeof ctx);
  472. explicit_bzero(results, sizeof results);
  473. errno = save_errno;
  474. return (0); /* satisfied */
  475. }