summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2005-01-13 15:20:42 +0000
committerAndy Polyakov <appro@openssl.org>2005-01-13 15:20:42 +0000
commit108159ffcc0a0e0e39b1316a1cf1aea7e985bdfb (patch)
tree939ac75f75b4cc5a9af0bf0c0a8cf19e52d2f203
parentc4d423511aa33fb0d8d8155a27fe05a294c1bd52 (diff)
downloadopenssl-new-108159ffcc0a0e0e39b1316a1cf1aea7e985bdfb.tar.gz
O_NOFOLLOW is not appropriate when opening /dev/* entries on Solaris.
PR: 998
-rw-r--r--crypto/rand/rand_unix.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
index abdab862e2..d861ab432c 100644
--- a/crypto/rand/rand_unix.c
+++ b/crypto/rand/rand_unix.c
@@ -121,6 +121,7 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/times.h>
+#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
@@ -152,9 +153,9 @@ int RAND_poll(void)
int n = 0;
#endif
#ifdef DEVRANDOM
- static const char *randomfiles[] = { DEVRANDOM, NULL };
- const char **randomfile = NULL;
- int fd;
+ static const char *randomfiles[] = { DEVRANDOM };
+ struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
+ int fd,i;
#endif
#ifdef DEVRANDOM_EGD
static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
@@ -162,13 +163,14 @@ int RAND_poll(void)
#endif
#ifdef DEVRANDOM
+ memset(randomstats,0,sizeof(randomstats));
/* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
* have this. Use /dev/urandom if you can as /dev/random may block
* if it runs out of random entries. */
- for (randomfile = randomfiles; *randomfile && n < ENTROPY_NEEDED; randomfile++)
+ for (i=0; i<sizeof(randomfiles)/sizeof(randomfiles[0]) && n < ENTROPY_NEEDED; i++)
{
- if ((fd = open(*randomfile, O_RDONLY
+ if ((fd = open(randomfiles[i], O_RDONLY
#ifdef O_NONBLOCK
|O_NONBLOCK
#endif
@@ -179,15 +181,24 @@ int RAND_poll(void)
our controlling tty */
|O_NOCTTY
#endif
-#ifdef O_NOFOLLOW /* Fail if the file is a symbolic link */
- |O_NOFOLLOW
-#endif
)) >= 0)
{
struct timeval t = { 0, 10*1000 }; /* Spend 10ms on
each file. */
- int r;
+ int r,j;
fd_set fset;
+ struct stat *st=&randomstats[i];
+
+ /* Avoid using same input... Used to be O_NOFOLLOW
+ * above, but it's not universally appropriate... */
+ if (fstat(fd,st) != 0) { close(fd); continue; }
+ for (j=0;j<i;j++)
+ {
+ if (randomstats[j].st_ino==st->st_ino &&
+ randomstats[j].st_dev!=st->st_dev)
+ break;
+ }
+ if (j<i) { close(fd); continue; }
do
{