Commit 108159ff authored by Andy Polyakov's avatar Andy Polyakov
Browse files

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

PR: 998
parent c4d42351
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -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
@@ -178,16 +180,25 @@ int RAND_poll(void)
#ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
		   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
				{