1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-04-17 15:44:34 +02:00

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
This commit is contained in:
Werner Koch 2015-01-19 16:46:05 +01:00
parent ed6287d2e1
commit 8adb5ff260
2 changed files with 22 additions and 15 deletions

View File

@ -117,28 +117,33 @@ rndlinux_gather_random( void (*add)(const void*, size_t, int), int requester,
#endif #endif
#endif #endif
while( length ) { while( length ) {
#ifdef FD_SETSIZE
fd_set rfds; fd_set rfds;
struct timeval tv; struct timeval tv;
int rc; int rc;
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = 3; tv.tv_sec = 3;
tv.tv_usec = 0; tv.tv_usec = 0;
if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) { if (fd < FD_SETSIZE)
if( !warn ) {
FD_SET(fd, &rfds);
if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
if( !warn )
tty_printf( tty_printf(
_("\n" _("\n"
"Not enough random bytes available. Please do some other work to give\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 ); "the OS a chance to collect more entropy! (Need %d more bytes)\n"), (int)length );
warn = 1; warn = 1;
continue; continue;
} }
else if( rc == -1 ) { else if( rc == -1 ) {
tty_printf( tty_printf(
"select() error: %s\n", strerror(errno)); "select() error: %s\n", strerror(errno));
continue; continue;
} }
}
#endif /*FD_SETSIZE*/
do { do {
int nbytes = length < sizeof(buffer)? length : sizeof(buffer); int nbytes = length < sizeof(buffer)? length : sizeof(buffer);

View File

@ -290,10 +290,10 @@ static struct RI {
/* This is a complex and screwball program. Some systems have things /* This is a complex and screwball program. Some systems have things
* like rX_dmn, x = integer, for RAID systems, but the statistics are * like rX_dmn, x = integer, for RAID systems, but the statistics are
* pretty dodgy */ * 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), { "/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 }, NULL, 0, 0, 0, 0 },
#endif #endif
#if 0 #if 0
/* The following aren't enabled since they're somewhat slow and not very /* The following aren't enabled since they're somewhat slow and not very
* unpredictable, however they give an indication of the sort of sources * 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); FD_ZERO(&fds);
for (i = 0; dataSources[i].path != NULL; i++) { for (i = 0; dataSources[i].path != NULL; i++) {
if (dataSources[i].pipe != NULL) { if (dataSources[i].pipe != NULL) {
/* FIXME: We need to make sure that PIPEFD is less
than FD_SETSIZE. */
FD_SET(dataSources[i].pipeFD, &fds); FD_SET(dataSources[i].pipeFD, &fds);
moreSources = 1; moreSources = 1;
} }
@ -707,7 +709,7 @@ start_gatherer( int pipefd )
#else #else
nmax = 20; /* assume a reasonable value */ nmax = 20; /* assume a reasonable value */
#endif #endif
{ {
int fd; int fd;
if ((fd = open ("/dev/null", O_RDWR)) != -1) { if ((fd = open ("/dev/null", O_RDWR)) != -1) {
dup2 (fd, STDIN_FILENO); dup2 (fd, STDIN_FILENO);