PERFORCE change 3222717: commit 1a55116834aad9a6fe7d3ea03e4a6998150eb2fb

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Change 3222717 by automation@vsergiienko-flipday-internal-rtd1395-nemo on 2022/11/02 14:06:37

	commit 1a55116834aad9a6fe7d3ea03e4a6998150eb2fb
	Author: Manjur Khan <mokhan@xxxxxxxx>
	Date:   Mon Oct 31 13:20:42 2022 -0700
	
	    REALTEK-9066 credit-rng to Nemo to fix FW-133531 by improving entropy at boot for WPA3 TLS OpenSSL+, patch-2 applied.
	    From git@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx:rtd1315x-stark/stark.git
	    From bf8a4000ed271b6772ec4562fa3309ed07bdaf0b
	    From: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx>
	    Date: Wed, 29 Dec 2021 22:10:03 +0100
	    Subject: [PATCH] random: fix crash on multiple early calls to
	     add_bootloader_randomness()
	    
	    Currently, if CONFIG_RANDOM_TRUST_BOOTLOADER is enabled, multiple calls
	    to add_bootloader_randomness() are broken and can cause a NULL pointer
	    dereference, as noted by Ivan T. Ivanov. This is not only a hypothetical
	    problem, as qemu on arm64 may provide bootloader entropy via EFI and via
	    devicetree.
	    
	    On the first call to add_hwgenerator_randomness(), crng_fast_load() is
	    executed, and if the seed is long enough, crng_init will be set to 1.
	    On subsequent calls to add_bootloader_randomness() and then to
	    add_hwgenerator_randomness(), crng_fast_load() will be skipped. Instead,
	    wait_event_interruptible() and then credit_entropy_bits() will be
	    called.
	    If the entropy count for that second seed is large enough, that proceeds
	    to crng_reseed().
	    
	    However, both wait_event_interruptible() and crng_reseed() depends
	    (at least in numa_crng_init()) on workqueues. Therefore, test whether
	    system_wq is already initialized, which is a sufficient indicator that
	    workqueue_init_early() has progressed far enough.
	    
	    If we wind up hitting the !system_wq case, we later want to do what
	    would have been done there when wqs are up, so set a flag, and do that
	    work later from the rand_initialize() call.
	    
	    Reported-by: Ivan T. Ivanov <iivanov@xxxxxxx>
	    Fixes: 18b915ac6b0a ("efi/random: Treat EFI_RNG_PROTOCOL output as
	    bootloader randomness")
	    Cc: stable@xxxxxxxxxxxxxxx
	    Signed-off-by: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx>
	    [Jason: added crng_need_done state and related logic.]
	    Signed-off-by: Jason A. Donenfeld <Jason@xxxxxxxxx>

Affected files ...

.. //depot/firmware/release/main/port/realtek/rtd1395/platform/software_phoenix/linux-kernel/drivers/char/random.c#3 edit

Differences ...

==== //depot/firmware/release/main/port/realtek/rtd1395/platform/software_phoenix/linux-kernel/drivers/char/random.c#3 (text) ====

@@ -432,6 +432,7 @@
  * its value (from 0->1->2).
  */
 static int crng_init = 0;
+static bool crng_need_final_init = false;
 #define crng_ready() (likely(crng_init > 1))
 static int crng_init_cnt = 0;
 static unsigned long crng_global_init_time = 0;
@@ -860,6 +861,36 @@
 static void numa_crng_init(void) {}
 #endif
 
+static void crng_finalize_init(struct crng_state *crng)
+{
+	if (crng != &primary_crng || crng_init >= 2)
+		return;
+	if (!system_wq) {
+		/* We can't call numa_crng_init until we have workqueues,
+		 * so mark this for processing later. */
+		crng_need_final_init = true;
+		return;
+	}
+
+	numa_crng_init();
+	crng_init = 2;
+	process_random_ready_list();
+	wake_up_interruptible(&crng_init_wait);
+	pr_notice("random: crng init done\n");
+	if (unseeded_warning.missed) {
+		pr_notice("random: %d get_random_xx warning(s) missed "
+				"due to ratelimiting\n",
+				unseeded_warning.missed);
+		unseeded_warning.missed = 0;
+	}
+	if (urandom_warning.missed) {
+		pr_notice("random: %d urandom warning(s) missed "
+				"due to ratelimiting\n",
+				urandom_warning.missed);
+		urandom_warning.missed = 0;
+	}
+}
+
 static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
 {
 	unsigned long	flags;
@@ -888,25 +919,7 @@
 	}
 	memzero_explicit(&buf, sizeof(buf));
 	crng->init_time = jiffies;
-	if (crng == &primary_crng && crng_init < 2) {
-		numa_crng_init();
-		crng_init = 2;
-		process_random_ready_list();
-		wake_up_interruptible(&crng_init_wait);
-		pr_notice("random: crng init done\n");
-		if (unseeded_warning.missed) {
-			pr_notice("random: %d get_random_xx warning(s) missed "
-				  "due to ratelimiting\n",
-				  unseeded_warning.missed);
-			unseeded_warning.missed = 0;
-		}
-		if (urandom_warning.missed) {
-			pr_notice("random: %d urandom warning(s) missed "
-				  "due to ratelimiting\n",
-				  urandom_warning.missed);
-			urandom_warning.missed = 0;
-		}
-	}
+	crng_finalize_init(crng);
 	spin_unlock_irqrestore(&crng->lock, flags);
 }
 
@@ -1717,6 +1730,8 @@
 {
 	init_std_data(&input_pool);
 	init_std_data(&blocking_pool);
+	if (crng_need_final_init)
+		crng_finalize_init(&primary_crng);
 	crng_initialize(&primary_crng);
 	crng_global_init_time = jiffies;
 	if (ratelimit_disable) {
@@ -2216,7 +2231,8 @@
 	 * We'll be woken up again once below random_write_wakeup_thresh,
 	 * or when the calling thread is about to terminate.
 	 */
-	wait_event_interruptible(random_write_wait, kthread_should_stop() ||
+	wait_event_interruptible(random_write_wait,
+			!system_wq || kthread_should_stop() ||
 			ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
 	mix_pool_bytes(poolp, buffer, count);
 	credit_entropy_bits(poolp, entropy);



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux