]> git.ipfire.org Git - thirdparty/rng-tools.git/commitdiff
Disable entropy source, if facing continued failures.
authorJeff Garzik <jeff@garzik.org>
Tue, 17 Aug 2010 19:59:01 +0000 (15:59 -0400)
committerJeff Garzik <jgarzik@redhat.com>
Tue, 17 Aug 2010 19:59:01 +0000 (15:59 -0400)
If all entropy sources are disabled, exit.

Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
rngd.c
rngd.h

diff --git a/rngd.c b/rngd.c
index 6ebef642b291e790a3943f660fd54cde127b76b4..6a7f1204c85f290cc930ff914165c6d9cfeafeb0 100644 (file)
--- 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 6e7e83fdf45deeba7ec6e989bfdba99058e9e7b7..bcc6f594bc3b4e1ca5f2d802805714ed08f85556 100644 (file)
--- a/rngd.h
+++ b/rngd.h
 
 #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;