aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2010-08-17 15:59:01 -0400
committerJeff Garzik <jgarzik@redhat.com>2010-08-17 15:59:01 -0400
commit62838c656e342608ab7aa4e58c567987e4342a55 (patch)
tree7d4821ddbf493ff3e2944907920e638a0d791ba9
parentecaa5676cd4df693108b2793e001c4c0b2456597 (diff)
downloadrng-tools-62838c656e342608ab7aa4e58c567987e4342a55.tar.gz
Disable entropy source, if facing continued failures.
If all entropy sources are disabled, exit. Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--rngd.c42
-rw-r--r--rngd.h7
2 files changed, 40 insertions, 9 deletions
diff --git a/rngd.c b/rngd.c
index 6ebef64..6a7f120 100644
--- a/rngd.c
+++ b/rngd.c
@@ -111,16 +111,12 @@ static struct rng rng_default = {
.rng_name = "/dev/hw_random",
.rng_fd = -1,
.xread = xread,
- .fipsctx = NULL,
- .next = NULL,
};
static struct rng rng_tpm = {
.rng_name = "/dev/tpm0",
.rng_fd = -1,
.xread = xread_tpm,
- .fipsctx = NULL,
- .next = NULL,
};
struct rng *rng_list;
@@ -207,18 +203,46 @@ static void do_loop(int random_step, double poll_timeout)
{
unsigned char buf[FIPS_RNG_BUFFER_SIZE];
int retval;
+ int no_work = 0;
- for (;;) {
+ while (no_work < 100) {
struct rng *iter;
+ bool work_done;
+
+ work_done = false;
for (iter = rng_list; iter; iter = iter->next)
{
+ int rc;
+
+ if (iter->disabled)
+ continue; /* failed, no work */
+
retval = iter->xread(buf, sizeof buf, iter);
- if (retval == 0)
- update_kernel_random(random_step,
- poll_timeout, buf,
- iter->fipsctx);
+ if (retval)
+ continue; /* failed, no work */
+
+ work_done = true;
+
+ rc = update_kernel_random(random_step,
+ poll_timeout, buf,
+ iter->fipsctx);
+ if (rc == 0)
+ continue; /* succeeded, work done */
+
+ iter->failures++;
+ if (iter->failures == MAX_RNG_FAILURES) {
+ message(LOG_DAEMON|LOG_ERR,
+ "too many FIPS failures, disabling entropy source\n");
+ iter->disabled = true;
+ }
}
+
+ if (!work_done)
+ no_work++;
}
+
+ message(LOG_DAEMON|LOG_ERR,
+ "No entropy sources working, exiting rngd\n");
}
int main(int argc, char **argv)
diff --git a/rngd.h b/rngd.h
index 6e7e83f..bcc6f59 100644
--- a/rngd.h
+++ b/rngd.h
@@ -27,11 +27,16 @@
#include <unistd.h>
#include <stdint.h>
+#include <stdbool.h>
#include <stdio.h>
#include <syslog.h>
#include "fips.h"
+enum {
+ MAX_RNG_FAILURES = 25,
+};
+
/* Command line arguments and processing */
struct arguments {
char *random_name;
@@ -49,6 +54,8 @@ extern struct arguments *arguments;
struct rng {
char *rng_name;
int rng_fd;
+ bool disabled;
+ int failures;
int (*xread) (void *buf, size_t size, struct rng *ent_src);
fips_ctx_t *fipsctx;