Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C223C433EF for ; Fri, 3 Dec 2021 16:47:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1382171AbhLCQvQ (ORCPT ); Fri, 3 Dec 2021 11:51:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57246 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230157AbhLCQvM (ORCPT ); Fri, 3 Dec 2021 11:51:12 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D3B87C061751; Fri, 3 Dec 2021 08:47:48 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5AC9D629F0; Fri, 3 Dec 2021 16:47:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E1511C53FCD; Fri, 3 Dec 2021 16:47:46 +0000 (UTC) Authentication-Results: smtp.kernel.org; dkim=pass (1024-bit key) header.d=zx2c4.com header.i=@zx2c4.com header.b="IjFJ+kAu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zx2c4.com; s=20210105; t=1638550065; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=22CT7nkuhiK6eO5WOZjdGRvypSs0c9qMdKw22cAO/GI=; b=IjFJ+kAuPQY8+czixhQsh668xb/89zi5BjlEhOagrwbksKMG2ljXwe/9MEQ9ey7+tfyeBq u/bumx1tM10GftxEQ3MrLnfPsl2Ee7/mdwsuZG5oHDk6PSYHkYN/0+ScCd7myv1RAKT8Vx mnA4R1G57jeilKcVt+IzWzWCYhUZSUE= Received: by mail.zx2c4.com (ZX2C4 Mail Server) with ESMTPSA id 9f4b23e7 (TLSv1.3:AEAD-AES256-GCM-SHA384:256:NO); Fri, 3 Dec 2021 16:47:45 +0000 (UTC) Message-ID: Date: Fri, 3 Dec 2021 17:47:41 +0100 MIME-Version: 1.0 Subject: Re: [PATCH v4] random: fix crash on multiple early calls to add_bootloader_randomness() Content-Language: en-US From: "Jason A. Donenfeld" To: Dominik Brodowski Cc: Theodore Ts'o , "Ivan T. Ivanov" , Ard Biesheuvel , linux-efi@vger.kernel.org, LKML , hsinyi@chromium.org References: <20211012082708.121931-1-iivanov@suse.de> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 12/3/21 16:39, Jason A. Donenfeld wrote: > Hi Dominik, > > Thanks for your analysis. Some more questions: > > On Fri, Dec 3, 2021 at 8:59 AM Dominik Brodowski > wrote: >> On subsequent calls to add_bootloader_randomness() and then to >> add_hwgenerator_randomness(), crng_fast_load() will be skipped. Instead, >> wait_event_interruptible() (which makes no sense for the init process) >> 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, crng_reseed() may depend on workqueues being available, which >> is not the case early during boot. > > It sounds like *the* issue you've identified is that crng_reseed() > calls into workqueue functions too early in init, right? The bug is > about paths into crng_reseed() that might cause that? > > If so, then specifically, are you referring to crng_reseed()'s call to > numa_crng_init()? In other words, the cause of the bug would be > 6c1e851c4edc ("random: fix possible sleeping allocation from irq > context")? If that's the case, then I wonder if the problem you're > seeing goes away if you revert both 6c1e851c4edc ("random: fix > possible sleeping allocation from irq context") and its primary > predecessor, 8ef35c866f88 ("random: set up the NUMA crng instances > after the CRNG is fully initialized"). These fix an actual bug, so I'm > not suggesting we actually revert these in the tree, but for the > purpose of testing, I'm wondering if this is actually the root cause > of the bug you're seeing. If the above holds, I wonder if something more basic like the below would do the trick -- deferring the bringup of the secondary pools until later on in rand_initialize. diff --git a/drivers/char/random.c b/drivers/char/random.c index c81485e2f126..e71b34bf9a2a 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -832,7 +832,6 @@ static void __init crng_initialize_primary(struct crng_state *crng) _extract_entropy(&input_pool, &crng->state[4], sizeof(__u32) * 12, 0); if (crng_init_try_arch_early(crng) && trust_cpu) { invalidate_batched_entropy(); - numa_crng_init(); crng_init = 2; pr_notice("crng done (trusting CPU's manufacturer)\n"); } @@ -840,13 +839,13 @@ static void __init crng_initialize_primary(struct crng_state *crng) } #ifdef CONFIG_NUMA -static void do_numa_crng_init(struct work_struct *work) +static void numa_crng_init(void) { int i; struct crng_state *crng; struct crng_state **pool; - pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); + pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL | __GFP_NOFAIL); for_each_online_node(i) { crng = kmalloc_node(sizeof(struct crng_state), GFP_KERNEL | __GFP_NOFAIL, i); @@ -861,13 +860,6 @@ static void do_numa_crng_init(struct work_struct *work) kfree(pool); } } - -static DECLARE_WORK(numa_crng_init_work, do_numa_crng_init); - -static void numa_crng_init(void) -{ - schedule_work(&numa_crng_init_work); -} #else static void numa_crng_init(void) {} #endif @@ -977,7 +969,6 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) spin_unlock_irqrestore(&crng->lock, flags); if (crng == &primary_crng && crng_init < 2) { invalidate_batched_entropy(); - numa_crng_init(); crng_init = 2; process_random_ready_list(); wake_up_interruptible(&crng_init_wait); @@ -1787,6 +1778,7 @@ int __init rand_initialize(void) { init_std_data(&input_pool); crng_initialize_primary(&primary_crng); + numa_crng_init(); crng_global_init_time = jiffies; if (ratelimit_disable) { urandom_warning.interval = 0;