aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2015-01-19 15:46:05 +0000
committerWerner Koch <[email protected]>2015-01-19 15:46:05 +0000
commit8adb5ff26062f717619aa816de8b27aa7d40d6c8 (patch)
tree674aaf985dcfdc94789cdcd641095cddbd21685f
parentdoc: Formatting fixes. (diff)
downloadgnupg-8adb5ff26062f717619aa816de8b27aa7d40d6c8.tar.gz
gnupg-8adb5ff26062f717619aa816de8b27aa7d40d6c8.zip
Fix a problem with select and high fds.
* cipher/rndlinux.c (rndlinux_gather_random): Check fd before using FD_SET. -- If on systems where the maximum number of fds may be dynamically configured to a value of FD_MAXSIZE or higher and the RNG is first used after more than FD_SETSIZE-1 descriptors are in use, we disable the progress messages from the RNG. A better solution would be too use poll but that requires more tests. The same problem exists in rndunix.c - however this rng is only used on old Unices and I assume that they don't feature dynamically configured maximum fd sizes. (from Libgcrypt commit 9487099071af4478d2882e633a0ade805801d6fa) This may fix GnuPG-bug-id: 1818
-rw-r--r--cipher/rndlinux.c29
-rw-r--r--cipher/rndunix.c8
2 files changed, 22 insertions, 15 deletions
diff --git a/cipher/rndlinux.c b/cipher/rndlinux.c
index 9d40f47b8..709a7ad54 100644
--- a/cipher/rndlinux.c
+++ b/cipher/rndlinux.c
@@ -117,28 +117,33 @@ rndlinux_gather_random( void (*add)(const void*, size_t, int), int requester,
#endif
#endif
while( length ) {
+#ifdef FD_SETSIZE
fd_set rfds;
struct timeval tv;
- int rc;
+ int rc;
FD_ZERO(&rfds);
- FD_SET(fd, &rfds);
tv.tv_sec = 3;
tv.tv_usec = 0;
- if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
- if( !warn )
+ if (fd < FD_SETSIZE)
+ {
+ FD_SET(fd, &rfds);
+ if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
+ if( !warn )
tty_printf(
_("\n"
"Not enough random bytes available. Please do some other work to give\n"
"the OS a chance to collect more entropy! (Need %d more bytes)\n"), (int)length );
- warn = 1;
- continue;
- }
- else if( rc == -1 ) {
- tty_printf(
- "select() error: %s\n", strerror(errno));
- continue;
- }
+ warn = 1;
+ continue;
+ }
+ else if( rc == -1 ) {
+ tty_printf(
+ "select() error: %s\n", strerror(errno));
+ continue;
+ }
+ }
+#endif /*FD_SETSIZE*/
do {
int nbytes = length < sizeof(buffer)? length : sizeof(buffer);
diff --git a/cipher/rndunix.c b/cipher/rndunix.c
index 75cf22ed0..72905e63b 100644
--- a/cipher/rndunix.c
+++ b/cipher/rndunix.c
@@ -290,10 +290,10 @@ static struct RI {
/* This is a complex and screwball program. Some systems have things
* like rX_dmn, x = integer, for RAID systems, but the statistics are
* pretty dodgy */
-#ifdef __QNXNTO__
+#ifdef __QNXNTO__
{ "/bin/pidin", "-F%A%B%c%d%E%I%J%K%m%M%n%N%p%P%S%s%T", SC(0.3),
NULL, 0, 0, 0, 0 },
-#endif
+#endif
#if 0
/* The following aren't enabled since they're somewhat slow and not very
* unpredictable, however they give an indication of the sort of sources
@@ -625,6 +625,8 @@ slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
FD_ZERO(&fds);
for (i = 0; dataSources[i].path != NULL; i++) {
if (dataSources[i].pipe != NULL) {
+ /* FIXME: We need to make sure that PIPEFD is less
+ than FD_SETSIZE. */
FD_SET(dataSources[i].pipeFD, &fds);
moreSources = 1;
}
@@ -707,7 +709,7 @@ start_gatherer( int pipefd )
#else
nmax = 20; /* assume a reasonable value */
#endif
- {
+ {
int fd;
if ((fd = open ("/dev/null", O_RDWR)) != -1) {
dup2 (fd, STDIN_FILENO);