4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Theodore Ts'o <ty...@mit.edu>

commit d848e5f8e1ebdb227d045db55fe4f825e82965fa upstream.

Add a new ioctl which forces the the crng to be reseeded.

Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Cc: sta...@kernel.org
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/char/random.c       |   13 ++++++++++++-
 include/uapi/linux/random.h |    3 +++
 2 files changed, 15 insertions(+), 1 deletion(-)

--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -436,6 +436,7 @@ struct crng_state primary_crng = {
 static int crng_init = 0;
 #define crng_ready() (likely(crng_init > 1))
 static int crng_init_cnt = 0;
+static unsigned long crng_global_init_time = 0;
 #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
 static void _extract_crng(struct crng_state *crng,
                          __u8 out[CHACHA20_BLOCK_SIZE]);
@@ -900,7 +901,8 @@ static void _extract_crng(struct crng_st
        unsigned long v, flags;
 
        if (crng_ready() &&
-           time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))
+           (time_after(crng_global_init_time, crng->init_time) ||
+            time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)))
                crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL);
        spin_lock_irqsave(&crng->lock, flags);
        if (arch_get_random_long(&v))
@@ -1689,6 +1691,7 @@ static int rand_initialize(void)
        init_std_data(&input_pool);
        init_std_data(&blocking_pool);
        crng_initialize(&primary_crng);
+       crng_global_init_time = jiffies;
        return 0;
 }
 early_initcall(rand_initialize);
@@ -1862,6 +1865,14 @@ static long random_ioctl(struct file *f,
                input_pool.entropy_count = 0;
                blocking_pool.entropy_count = 0;
                return 0;
+       case RNDRESEEDCRNG:
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               if (crng_init < 2)
+                       return -ENODATA;
+               crng_reseed(&primary_crng, NULL);
+               crng_global_init_time = jiffies - 1;
+               return 0;
        default:
                return -EINVAL;
        }
--- a/include/uapi/linux/random.h
+++ b/include/uapi/linux/random.h
@@ -34,6 +34,9 @@
 /* Clear the entropy pool and associated counters.  (Superuser only.) */
 #define RNDCLEARPOOL   _IO( 'R', 0x06 )
 
+/* Reseed CRNG.  (Superuser only.) */
+#define RNDRESEEDCRNG  _IO( 'R', 0x07 )
+
 struct rand_pool_info {
        int     entropy_count;
        int     buf_size;


Reply via email to