O_NOFOLLOW is not appropriate when opening /dev/* entries on Solaris.

PR: 998
This commit is contained in:
Andy Polyakov 2005-01-14 16:19:47 +00:00
parent 086b64d0d3
commit adeb20b6b7

View file

@ -120,6 +120,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/times.h> #include <sys/times.h>
#include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
@ -151,9 +152,9 @@ int RAND_poll(void)
int n = 0; int n = 0;
#endif #endif
#ifdef DEVRANDOM #ifdef DEVRANDOM
static const char *randomfiles[] = { DEVRANDOM, NULL }; static const char *randomfiles[] = { DEVRANDOM };
const char **randomfile = NULL; struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
int fd; int fd,i;
#endif #endif
#ifdef DEVRANDOM_EGD #ifdef DEVRANDOM_EGD
static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
@ -161,13 +162,14 @@ int RAND_poll(void)
#endif #endif
#ifdef DEVRANDOM #ifdef DEVRANDOM
memset(randomstats,0,sizeof(randomstats));
/* Use a random entropy pool device. Linux, FreeBSD and OpenBSD /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
* have this. Use /dev/urandom if you can as /dev/random may block * have this. Use /dev/urandom if you can as /dev/random may block
* if it runs out of random entries. */ * 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 #ifdef O_NONBLOCK
|O_NONBLOCK |O_NONBLOCK
#endif #endif
@ -177,16 +179,25 @@ int RAND_poll(void)
#ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it #ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
our controlling tty */ our controlling tty */
|O_NOCTTY |O_NOCTTY
#endif
#ifdef O_NOFOLLOW /* Fail if the file is a symbolic link */
|O_NOFOLLOW
#endif #endif
)) >= 0) )) >= 0)
{ {
struct timeval t = { 0, 10*1000 }; /* Spend 10ms on struct timeval t = { 0, 10*1000 }; /* Spend 10ms on
each file. */ each file. */
int r; int r,j;
fd_set fset; 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 do
{ {