Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp43478pxb; Wed, 23 Mar 2022 12:38:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx2MAa4asZQjnpxnNaWvCoMF4UnY5hEiM+wBJg6OPgFiQtXKMYXKJpW6U1zbJciRfDX7064 X-Received: by 2002:a05:6402:1742:b0:419:2707:747a with SMTP id v2-20020a056402174200b004192707747amr2256004edx.238.1648064328230; Wed, 23 Mar 2022 12:38:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648064328; cv=none; d=google.com; s=arc-20160816; b=tX2lvpGK1FjGngfLgibIbZDCGNWkkE0O4jYfBt72KRRJA3yc2w0lkH+1PCkUY7gyat 7Hev+HNjN1f1GWLLP05OXYBjdJGy+vijB5MjNhnDKaeqmTYrWVOckZfSPGO9GbpIHAPJ W3aUy/CiM8+XDe94gyEjytGQXuKAoZM5XLqyIukDd38fOsJKpH03TwCk6fQYvh5i5ukY zfKhwFxLfdFSavoHjQimKzOV79Dfstmv9+tF19TkVFRUfDoevNgbvPEwfZLzXHT+HHrA ulqy94JM5IM0o4XNcMv/+AFCKlRi+LyP94GXlxnyqp9tGRCRP+dk/0uRYbpT9EJmY/gx M1AQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=rArObsGrIA+CZzY+aR2vyQPSwI1FLNZscc57zebd6IA=; b=I87XL3TjV9qgicAU+vzG0Pza0qOxd4X40Xc6xDPgn6VZPx72Y17P4pwfjedJCn4tVx TA70CkSoCy6A0EtCKu6+dE7rZJK/pG65P3Sre/hu3M618j1xhI3UWIrH11ouVUSwPTt3 VDjQ2bNhatTS+3FJr9TKLut0ohvMSXuJ8xFmmpRgFQesiI6Fk7KyFVtVEv6ctIcTcI5n BQOBjhNT9X+K8O7RN7Is7I7IryMNzqV4dqrHBZ9q4G76E1Tta75ZYWdHyjE1KU1Re6tK a35723fIrZslOyzSGur1S0/1VR1rZuSpGwwVp/VkbRUO2WiiK56lsVbJbIQpOeLPTXkI vHAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@zx2c4.com header.s=20210105 header.b=B8jjZXYB; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zx2c4.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ss24-20020a170907c01800b006dfd81499c7si9921020ejc.828.2022.03.23.12.38.12; Wed, 23 Mar 2022 12:38:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@zx2c4.com header.s=20210105 header.b=B8jjZXYB; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zx2c4.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229436AbiCWEC0 (ORCPT + 99 others); Wed, 23 Mar 2022 00:02:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55066 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229446AbiCWECZ (ORCPT ); Wed, 23 Mar 2022 00:02:25 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10F36403EF; Tue, 22 Mar 2022 21:00:56 -0700 (PDT) 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 8FDB86152F; Wed, 23 Mar 2022 04:00:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1DB13C340E8; Wed, 23 Mar 2022 04:00:54 +0000 (UTC) Authentication-Results: smtp.kernel.org; dkim=pass (1024-bit key) header.d=zx2c4.com header.i=@zx2c4.com header.b="B8jjZXYB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zx2c4.com; s=20210105; t=1648008052; 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=rArObsGrIA+CZzY+aR2vyQPSwI1FLNZscc57zebd6IA=; b=B8jjZXYBZhomYifjoxrnHX0BOz4rDhGe68SOXLYYABff4xVw2pBFTu3S7+x6j5RjayefSL LHQ9qQlqfmM0AAM953ycgmzLda363Otc3cIEmN8WvYof5TIsi8zrKYwQQqRYGMbP89exwr LnU+Fh+VZbp5DHtSsZB1vn7sUbI45+g= Received: by mail.zx2c4.com (ZX2C4 Mail Server) with ESMTPSA id 19660a94 (TLSv1.3:AEAD-AES256-GCM-SHA384:256:NO); Wed, 23 Mar 2022 04:00:52 +0000 (UTC) Date: Tue, 22 Mar 2022 22:00:49 -0600 From: "Jason A. Donenfeld" To: Theodore Ts'o Cc: linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org, Linus Torvalds , Guenter Roeck , Dominik Brodowski , Jann Horn Subject: Re: [PATCH] random: allow writes to /dev/urandom to influence fast init Message-ID: References: <20220322191436.110963-1-Jason@zx2c4.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Hi Ted, On Tue, Mar 22, 2022 at 9:35 PM Theodore Ts'o wrote: > One of the big issues with /dev/urandom writes is that *anyone*, > including malicious user space, can force specific bytes to be mixed > in.  That's the source of the reluctance to immediate use inputs from > writes into /dev/[u]random until there is a chance for it to be mixed > in with other entropy which is hopefully not under the control of > malicious userspace. Right, sort of. Since we now always use a cryptographic hash function, we can haphazardly mix whatever any user wants, without too much concern. The issue is whether we _credit_ those bits. Were we to credit those bits, a malicious unpriv'd user could credit 248 bits of known input, and then bruteforce 8 bits of unknown input, and repeat, and in that way destroy the security of the thing. So, yea, the current reluctance does make sense. > Now, I recognize that things are a bit special in early boot, and if > we have a malicious script running in a systemd unit script, we might > as well go home.  But something to consider is whether we want to do > soemthing special if the process writing to /dev/[u]random has > CAP_SYS_ADMIN, or some such. Exactly. So one way of approaching this would be to simply credit writes to /dev/urandom if it's CAP_SYS_ADMIN and maybe if also !crng_ready(), and just skip the crng_pre_init_inject() part that this current patch adds. I'll attach a sample patch of what this might look like at the end of this email. The problem with that approach, though, is that various userspaces might already write garbage into /dev/urandom, not expecting them to be credited -- for example, some userspace hardware configuration component that writes some serial number there. So I'm sort of hesitant to _change_ the behavior that we've had for so long. Another variation on that would be to do what this current patch does, but only crng_pre_init_inject() on CAP_SYS_ADMIN. But this has the same pitfall of only working as intended at cnrg_init=0 but not crng_init=1. That's better than nothing, but it's not perfect, and it introduces that problem with RNDADDTOENTCNT. Also, to echo the point I made in the email I just sent to David, this has _always_ been broken, and those shell scripts have _always_ been vulnerable. Maybe the kernel should fix that, but due to the ambiguity of the /dev/urandom write interface, maybe the best fix is actually in userspace itself, which means it'd work on old kernels too (which are rather common for the embedded devices that tend to have those types of shell scripts). Specifically, I'm talking about this fix I did for systemd: https://github.com/systemd/systemd/commit/da2862ef06f22fc8d31dafced6d2d6dc14f2ee0b And then the same fix that I just submitted this evening for Buildroot: https://lists.buildroot.org/pipermail/buildroot/2022-March/639359.html It seems like hashing the old seed together with the new one ought to be a good standard practice to mitigate against all sorts of bugs. > Yeah, no one should ever ver ever be using RNDADDTOENTCNT.  It's an > ioctl which requires root privilegs, and if it breaks, you get to keep > both pieces. > > > And perhaps we might consider attempting to deprecate RNDADDTOENTCNT at > > some point in the future. > > That would be a good idea.  :-) Oh cool, I'm glad you agree. Let's do that then. Have a preferred path? Maybe just a pr_once() saying not to use it? Jason --------8<------------------------------------------- The CAP_SYS_ADMIN idea, maybe not so good, but here for illustration: diff --git a/drivers/char/random.c b/drivers/char/random.c index 706f08edf0dc..d1dc46366647 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1493,12 +1493,16 @@ static __poll_t random_poll(struct file *file, poll_table *wait) return mask; } -static int write_pool(const char __user *ubuf, size_t count) +static int write_pool(const char __user *ubuf, size_t count, bool credit_at_boot) { - size_t len; + size_t len, bits; int ret = 0; u8 block[BLAKE2S_BLOCK_SIZE]; + if (count > SIZE_MAX / 8) + return -EINVAL; + bits = count * 8; + while (count) { len = min(count, sizeof(block)); if (copy_from_user(block, ubuf, len)) { @@ -1511,6 +1515,9 @@ static int write_pool(const char __user *ubuf, size_t count) cond_resched(); } + if (credit_at_boot && !crng_ready() && capable(CAP_SYS_ADMIN)) + credit_entropy_bits(bits); + out: memzero_explicit(block, sizeof(block)); return ret; @@ -1521,7 +1528,7 @@ static ssize_t random_write(struct file *file, const char __user *buffer, { int ret; - ret = write_pool(buffer, count); + ret = write_pool(buffer, count, true); if (ret) return ret; @@ -1584,7 +1591,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) return -EINVAL; if (get_user(size, p++)) return -EFAULT; - retval = write_pool((const char __user *)p, size); + retval = write_pool((const char __user *)p, size, false); if (retval < 0) return retval; credit_entropy_bits(ent_count);