diff options
author | Werner Koch <[email protected]> | 2015-01-19 15:46:05 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2015-01-19 15:46:05 +0000 |
commit | 8adb5ff26062f717619aa816de8b27aa7d40d6c8 (patch) | |
tree | 674aaf985dcfdc94789cdcd641095cddbd21685f | |
parent | doc: Formatting fixes. (diff) | |
download | gnupg-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.c | 29 | ||||
-rw-r--r-- | cipher/rndunix.c | 8 |
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); |