vsprintf: initialize siphash key using notifier
authorJason A. Donenfeld <Jason@zx2c4.com>
Wed, 16 Nov 2022 16:16:38 +0000 (17:16 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Tue, 22 Nov 2022 13:53:31 +0000 (14:53 +0100)
Rather than polling every second, use the new notifier to do this at
exactly the right moment.

Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
lib/vsprintf.c

index 24f37ba..2d11541 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/siphash.h>
 #include <linux/compiler.h>
 #include <linux/property.h>
+#include <linux/notifier.h>
 #ifdef CONFIG_BLOCK
 #include <linux/blkdev.h>
 #endif
@@ -752,26 +753,21 @@ early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable);
 
 static bool filled_random_ptr_key __read_mostly;
 static siphash_key_t ptr_key __read_mostly;
-static void fill_ptr_key_workfn(struct work_struct *work);
-static DECLARE_DELAYED_WORK(fill_ptr_key_work, fill_ptr_key_workfn);
 
-static void fill_ptr_key_workfn(struct work_struct *work)
+static int fill_ptr_key(struct notifier_block *nb, unsigned long action, void *data)
 {
-       if (!rng_is_initialized()) {
-               queue_delayed_work(system_unbound_wq, &fill_ptr_key_work, HZ  * 2);
-               return;
-       }
-
        get_random_bytes(&ptr_key, sizeof(ptr_key));
 
        /* Pairs with smp_rmb() before reading ptr_key. */
        smp_wmb();
        WRITE_ONCE(filled_random_ptr_key, true);
+       return NOTIFY_DONE;
 }
 
 static int __init vsprintf_init_hashval(void)
 {
-       fill_ptr_key_workfn(NULL);
+       static struct notifier_block fill_ptr_key_nb = { .notifier_call = fill_ptr_key };
+       execute_with_initialized_rng(&fill_ptr_key_nb);
        return 0;
 }
 subsys_initcall(vsprintf_init_hashval)