summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/arc4random/getentropy_solaris.c52
-rw-r--r--src/lib/libcrypto/crypto/getentropy_solaris.c52
2 files changed, 68 insertions, 36 deletions
diff --git a/src/lib/libcrypto/arc4random/getentropy_solaris.c b/src/lib/libcrypto/arc4random/getentropy_solaris.c
index 6aeb8713ab..13afe7e3c9 100644
--- a/src/lib/libcrypto/arc4random/getentropy_solaris.c
+++ b/src/lib/libcrypto/arc4random/getentropy_solaris.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: getentropy_solaris.c,v 1.1 2014/07/08 10:45:35 beck Exp $ */ 1/* $OpenBSD: getentropy_solaris.c,v 1.2 2014/07/12 13:19:44 beck Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org> 4 * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -66,7 +66,8 @@ int getentropy(void *buf, size_t len);
66 66
67extern int main(int, char *argv[]); 67extern int main(int, char *argv[]);
68static int gotdata(char *buf, size_t len); 68static int gotdata(char *buf, size_t len);
69static int getentropy_urandom(void *buf, size_t len); 69static int getentropy_urandom(void *buf, size_t len, const char *path,
70 int devfscheck);
70static int getentropy_fallback(void *buf, size_t len); 71static int getentropy_fallback(void *buf, size_t len);
71 72
72int 73int
@@ -80,20 +81,39 @@ getentropy(void *buf, size_t len)
80 } 81 }
81 82
82 /* 83 /*
83 * Try to get entropy with /dev/urandom 84 * Try to get entropy with /dev/urandom...
85 *
86 * Solaris provides /dev/urandom as a symbolic link to
87 * /devices/pseudo/random@0:urandom which is provided by
88 * a devfs filesystem. Best practice is to use O_NOFOLLOW,
89 * so we must try the unpublished name directly.
90 *
91 * This can fail if the process is inside a chroot which lacks
92 * the devfs mount, or if file descriptors are exhausted.
93 */
94 ret = getentropy_urandom(buf, len,
95 "/devices/pseudo/random@0:urandom", 1);
96 if (ret != -1)
97 return (ret);
98
99 /*
100 * Unfortunately, chroot spaces on Solaris are sometimes setup
101 * with direct device node of the well-known /dev/urandom name
102 * (perhaps to avoid dragging all of devfs into the space).
84 * 103 *
85 * This can fail if the process is inside a chroot or if file 104 * This can fail if the process is inside a chroot or if file
86 * descriptors are exhausted. 105 * descriptors are exhausted.
87 */ 106 */
88 ret = getentropy_urandom(buf, len); 107 ret = getentropy_urandom(buf, len, "/dev/urandom", 0);
89 if (ret != -1) 108 if (ret != -1)
90 return (ret); 109 return (ret);
110
91 /* 111 /*
92 * Entropy collection via /dev/urandom and sysctl have failed. 112 * Entropy collection via /dev/urandom has failed.
93 * 113 *
94 * No other API exists for collecting entropy, and we have 114 * No other API exists for collecting entropy, and we have
95 * no failsafe way to get it on Solaris that is not sensitive 115 * no failsafe way to get it on Solaris that is not sensitive
96 * to resource exhaustion. 116 * to resource exhaustion.
97 * 117 *
98 * We have very few options: 118 * We have very few options:
99 * - Even syslog_r is unsafe to call at this low level, so 119 * - Even syslog_r is unsafe to call at this low level, so
@@ -141,7 +161,7 @@ gotdata(char *buf, size_t len)
141} 161}
142 162
143static int 163static int
144getentropy_urandom(void *buf, size_t len) 164getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
145{ 165{
146 struct stat st; 166 struct stat st;
147 size_t i; 167 size_t i;
@@ -150,19 +170,14 @@ getentropy_urandom(void *buf, size_t len)
150 170
151start: 171start:
152 172
153 flags = O_RDONLY; 173 flags = O_RDONLY;
154#ifdef O_NOFOLLOW 174#ifdef O_NOFOLLOW
155 flags |= O_NOFOLLOW; 175 flags |= O_NOFOLLOW;
156#endif 176#endif
157#ifdef O_CLOEXEC 177#ifdef O_CLOEXEC
158 flags |= O_CLOEXEC; 178 flags |= O_CLOEXEC;
159#endif 179#endif
160 /* 180 fd = open(path, flags, 0);
161 * Solaris provides /dev/urandom as a symbolic link.
162 * /devices/pseudo/random@0:urandom should be the
163 * real device path, and we do want O_NOFOLLOW.
164 */
165 fd = open("/devices/pseudo/random@0:urandom", flags, 0);
166 if (fd == -1) { 181 if (fd == -1) {
167 if (errno == EINTR) 182 if (errno == EINTR)
168 goto start; 183 goto start;
@@ -173,7 +188,8 @@ start:
173#endif 188#endif
174 189
175 /* Lightly verify that the device node looks sane */ 190 /* Lightly verify that the device node looks sane */
176 if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) { 191 if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode) ||
192 (devfscheck && (strcmp(st.st_fstype, "devfs") != 0))) {
177 close(fd); 193 close(fd);
178 goto nodevrandom; 194 goto nodevrandom;
179 } 195 }
diff --git a/src/lib/libcrypto/crypto/getentropy_solaris.c b/src/lib/libcrypto/crypto/getentropy_solaris.c
index 6aeb8713ab..13afe7e3c9 100644
--- a/src/lib/libcrypto/crypto/getentropy_solaris.c
+++ b/src/lib/libcrypto/crypto/getentropy_solaris.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: getentropy_solaris.c,v 1.1 2014/07/08 10:45:35 beck Exp $ */ 1/* $OpenBSD: getentropy_solaris.c,v 1.2 2014/07/12 13:19:44 beck Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org> 4 * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -66,7 +66,8 @@ int getentropy(void *buf, size_t len);
66 66
67extern int main(int, char *argv[]); 67extern int main(int, char *argv[]);
68static int gotdata(char *buf, size_t len); 68static int gotdata(char *buf, size_t len);
69static int getentropy_urandom(void *buf, size_t len); 69static int getentropy_urandom(void *buf, size_t len, const char *path,
70 int devfscheck);
70static int getentropy_fallback(void *buf, size_t len); 71static int getentropy_fallback(void *buf, size_t len);
71 72
72int 73int
@@ -80,20 +81,39 @@ getentropy(void *buf, size_t len)
80 } 81 }
81 82
82 /* 83 /*
83 * Try to get entropy with /dev/urandom 84 * Try to get entropy with /dev/urandom...
85 *
86 * Solaris provides /dev/urandom as a symbolic link to
87 * /devices/pseudo/random@0:urandom which is provided by
88 * a devfs filesystem. Best practice is to use O_NOFOLLOW,
89 * so we must try the unpublished name directly.
90 *
91 * This can fail if the process is inside a chroot which lacks
92 * the devfs mount, or if file descriptors are exhausted.
93 */
94 ret = getentropy_urandom(buf, len,
95 "/devices/pseudo/random@0:urandom", 1);
96 if (ret != -1)
97 return (ret);
98
99 /*
100 * Unfortunately, chroot spaces on Solaris are sometimes setup
101 * with direct device node of the well-known /dev/urandom name
102 * (perhaps to avoid dragging all of devfs into the space).
84 * 103 *
85 * This can fail if the process is inside a chroot or if file 104 * This can fail if the process is inside a chroot or if file
86 * descriptors are exhausted. 105 * descriptors are exhausted.
87 */ 106 */
88 ret = getentropy_urandom(buf, len); 107 ret = getentropy_urandom(buf, len, "/dev/urandom", 0);
89 if (ret != -1) 108 if (ret != -1)
90 return (ret); 109 return (ret);
110
91 /* 111 /*
92 * Entropy collection via /dev/urandom and sysctl have failed. 112 * Entropy collection via /dev/urandom has failed.
93 * 113 *
94 * No other API exists for collecting entropy, and we have 114 * No other API exists for collecting entropy, and we have
95 * no failsafe way to get it on Solaris that is not sensitive 115 * no failsafe way to get it on Solaris that is not sensitive
96 * to resource exhaustion. 116 * to resource exhaustion.
97 * 117 *
98 * We have very few options: 118 * We have very few options:
99 * - Even syslog_r is unsafe to call at this low level, so 119 * - Even syslog_r is unsafe to call at this low level, so
@@ -141,7 +161,7 @@ gotdata(char *buf, size_t len)
141} 161}
142 162
143static int 163static int
144getentropy_urandom(void *buf, size_t len) 164getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
145{ 165{
146 struct stat st; 166 struct stat st;
147 size_t i; 167 size_t i;
@@ -150,19 +170,14 @@ getentropy_urandom(void *buf, size_t len)
150 170
151start: 171start:
152 172
153 flags = O_RDONLY; 173 flags = O_RDONLY;
154#ifdef O_NOFOLLOW 174#ifdef O_NOFOLLOW
155 flags |= O_NOFOLLOW; 175 flags |= O_NOFOLLOW;
156#endif 176#endif
157#ifdef O_CLOEXEC 177#ifdef O_CLOEXEC
158 flags |= O_CLOEXEC; 178 flags |= O_CLOEXEC;
159#endif 179#endif
160 /* 180 fd = open(path, flags, 0);
161 * Solaris provides /dev/urandom as a symbolic link.
162 * /devices/pseudo/random@0:urandom should be the
163 * real device path, and we do want O_NOFOLLOW.
164 */
165 fd = open("/devices/pseudo/random@0:urandom", flags, 0);
166 if (fd == -1) { 181 if (fd == -1) {
167 if (errno == EINTR) 182 if (errno == EINTR)
168 goto start; 183 goto start;
@@ -173,7 +188,8 @@ start:
173#endif 188#endif
174 189
175 /* Lightly verify that the device node looks sane */ 190 /* Lightly verify that the device node looks sane */
176 if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) { 191 if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode) ||
192 (devfscheck && (strcmp(st.st_fstype, "devfs") != 0))) {
177 close(fd); 193 close(fd);
178 goto nodevrandom; 194 goto nodevrandom;
179 } 195 }