summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--random/ChangeLog5
-rw-r--r--random/rndlinux.c50
-rw-r--r--random/rndunix.c3
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;