diff options
-rw-r--r-- | random/ChangeLog | 5 | ||||
-rw-r--r-- | random/rndlinux.c | 50 | ||||
-rw-r--r-- | random/rndunix.c | 3 |
3 files changed, 37 insertions, 21 deletions
diff --git a/random/ChangeLog b/random/ChangeLog index 7784d44e..b7a0d5a1 100644 --- a/random/ChangeLog +++ b/random/ChangeLog @@ -1,3 +1,8 @@ +2011-09-08 Werner Koch <wk@g10code.com> + + * rndlinux.c (_gcry_rndlinux_gather_random): Don't use select if + the fd number is too high. Reported by Jakub Bogusz. + 2010-10-18 Werner Koch <wk@g10code.com> * rndw32.c (registry_poll): Disable performace fata gathering if diff --git a/random/rndlinux.c b/random/rndlinux.c index 5b84a19c..b304cc9e 100644 --- a/random/rndlinux.c +++ b/random/rndlinux.c @@ -134,29 +134,39 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t, struct timeval tv; int rc; - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = delay; - tv.tv_usec = delay? 0 : 100000; - if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) + /* If the system has no limit on the number of file descriptors + and we encounter an fd which is larger than the fd_set size, + we don't use the select at all. The select code is only used + to emit progress messages. A better solution would be to + fall back to poll() if available. */ +#ifdef FD_SETSIZE + if (fd < FD_SETSIZE) +#endif { - if (!any_need_entropy || last_so_far != (want - length) ) + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + tv.tv_sec = delay; + tv.tv_usec = delay? 0 : 100000; + if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) { - last_so_far = want - length; - _gcry_random_progress ("need_entropy", 'X', - (int)last_so_far, (int)want); - any_need_entropy = 1; - } - delay = 3; /* Use 3 seconds henceforth. */ - continue; - } - else if( rc == -1 ) - { - log_error ("select() error: %s\n", strerror(errno)); - if (!delay) - delay = 1; /* Use 1 second if we encounter an error before + if (!any_need_entropy || last_so_far != (want - length) ) + { + last_so_far = want - length; + _gcry_random_progress ("need_entropy", 'X', + (int)last_so_far, (int)want); + any_need_entropy = 1; + } + delay = 3; /* Use 3 seconds henceforth. */ + continue; + } + else if( rc == -1 ) + { + log_error ("select() error: %s\n", strerror(errno)); + if (!delay) + delay = 1; /* Use 1 second if we encounter an error before we have ever blocked. */ - continue; + continue; + } } do diff --git a/random/rndunix.c b/random/rndunix.c index cc5eb145..1b810d72 100644 --- a/random/rndunix.c +++ b/random/rndunix.c @@ -551,7 +551,8 @@ slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes ) #else #error O_NONBLOCK is missing #endif - + /* FIXME: We need to make sure that the fd is less than + FD_SETSIZE. */ FD_SET(dataSources[i].pipeFD, &fds); dataSources[i].length = 0; |