diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/arc4random/getentropy_solaris.c | 52 | ||||
-rw-r--r-- | src/lib/libcrypto/crypto/getentropy_solaris.c | 52 |
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 | ||
67 | extern int main(int, char *argv[]); | 67 | extern int main(int, char *argv[]); |
68 | static int gotdata(char *buf, size_t len); | 68 | static int gotdata(char *buf, size_t len); |
69 | static int getentropy_urandom(void *buf, size_t len); | 69 | static int getentropy_urandom(void *buf, size_t len, const char *path, |
70 | int devfscheck); | ||
70 | static int getentropy_fallback(void *buf, size_t len); | 71 | static int getentropy_fallback(void *buf, size_t len); |
71 | 72 | ||
72 | int | 73 | int |
@@ -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 | ||
143 | static int | 163 | static int |
144 | getentropy_urandom(void *buf, size_t len) | 164 | getentropy_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 | ||
151 | start: | 171 | start: |
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 | ||
67 | extern int main(int, char *argv[]); | 67 | extern int main(int, char *argv[]); |
68 | static int gotdata(char *buf, size_t len); | 68 | static int gotdata(char *buf, size_t len); |
69 | static int getentropy_urandom(void *buf, size_t len); | 69 | static int getentropy_urandom(void *buf, size_t len, const char *path, |
70 | int devfscheck); | ||
70 | static int getentropy_fallback(void *buf, size_t len); | 71 | static int getentropy_fallback(void *buf, size_t len); |
71 | 72 | ||
72 | int | 73 | int |
@@ -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 | ||
143 | static int | 163 | static int |
144 | getentropy_urandom(void *buf, size_t len) | 164 | getentropy_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 | ||
151 | start: | 171 | start: |
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 | } |