From patchwork Wed Apr 19 17:01:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 13217153 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 DB784C6FD18 for ; Wed, 19 Apr 2023 17:01:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233079AbjDSRBz (ORCPT ); Wed, 19 Apr 2023 13:01:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56798 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232779AbjDSRBx (ORCPT ); Wed, 19 Apr 2023 13:01:53 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 911E86A5B for ; Wed, 19 Apr 2023 10:01:52 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 22CEE152B; Wed, 19 Apr 2023 10:02:36 -0700 (PDT) Received: from donnerap.arm.com (donnerap.cambridge.arm.com [10.1.197.42]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5BF803F5A1; Wed, 19 Apr 2023 10:01:51 -0700 (PDT) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: kvm@vger.kernel.org, Alexandru Elisei , Sami Mujawar , Jean-Philippe Brucker , Marc Zyngier Subject: [PATCH kvmtool v2 1/2] virtio/rng: switch to using /dev/urandom Date: Wed, 19 Apr 2023 18:01:35 +0100 Message-Id: <20230419170136.1883584-2-andre.przywara@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230419170136.1883584-1-andre.przywara@arm.com> References: <20230419170136.1883584-1-andre.przywara@arm.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org At the moment we use /dev/random as the backing device to provide random numbers to our virtio-rng implementation. The downside of doing so is that it may block indefinitely - or return EAGAIN repeatedly in our case. On one headless system without ample noise sources (no keyboard, mouse, or network traffic) I measured 30 seconds to gain one byte of randomness. At the moment EDK II insists in waiting for all of the requsted random bytes (for its EFI_RNG_PROTOCOL runtime service) to arrive, that held up a Linux kernel boot for more than 10 minutes(!). According to the Internet(TM), on Linux /dev/urandom provides the same quality random numbers as /dev/random, it just does not block when the entropy estimation algorithm suggests so. For all practical purposes the recommendation is to just use /dev/urandom, QEMU did the switch as well in 2019 [1]. Use /dev/urandom instead of /dev/random when opening the file descriptor providing the randomness source for the virtio/rng implementation. Due to a special behaviour documented on the urandom(4) manpage, a read from /dev/urandom will never block, so we can drop the O_NONBLOCK flag. [1] https://gitlab.com/qemu-project/qemu/-/commit/a2230bd778d8 Signed-off-by: Andre Przywara Reviewed-by: Jean-Philippe Brucker --- virtio/rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virtio/rng.c b/virtio/rng.c index 8f85d5ec1..e6e70ced3 100644 --- a/virtio/rng.c +++ b/virtio/rng.c @@ -166,7 +166,7 @@ int virtio_rng__init(struct kvm *kvm) if (rdev == NULL) return -ENOMEM; - rdev->fd = open("/dev/random", O_RDONLY | O_NONBLOCK); + rdev->fd = open("/dev/urandom", O_RDONLY); if (rdev->fd < 0) { r = rdev->fd; goto cleanup; From patchwork Wed Apr 19 17:05:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 13217154 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 2E2BEC77B73 for ; Wed, 19 Apr 2023 17:05:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233644AbjDSRFi (ORCPT ); Wed, 19 Apr 2023 13:05:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233581AbjDSRFd (ORCPT ); Wed, 19 Apr 2023 13:05:33 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0A6BC7EF6 for ; Wed, 19 Apr 2023 10:05:32 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 913CE1424; Wed, 19 Apr 2023 10:06:15 -0700 (PDT) Received: from donnerap.arm.com (donnerap.cambridge.arm.com [10.1.197.42]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id AF1D43F5A1; Wed, 19 Apr 2023 10:05:30 -0700 (PDT) From: Andre Przywara To: Will Deacon , Julien Thierry Cc: kvm@vger.kernel.org, Alexandru Elisei , Sami Mujawar , Jean-Philippe Brucker , Marc Zyngier Subject: [PATCH kvmtool v2 2/2] virtio/rng: return at least one byte of entropy Date: Wed, 19 Apr 2023 18:05:26 +0100 Message-Id: <20230419170526.1883812-1-andre.przywara@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230419170136.1883584-2-andre.przywara@arm.com> References: <20230419170136.1883584-2-andre.przywara@arm.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org In contrast to the original v0.9 virtio spec (which was rather vague), the virtio 1.0+ spec demands that a RNG request returns at least one byte: "The device MUST place one or more random bytes into the buffer, but it MAY use less than the entire buffer length." Our current implementation does not prevent returning zero bytes, which upsets an assert in EDK II. /dev/urandom should always return at least 256 bytes of entropy, unless interrupted by a signal. Repeat the read if that happens, and give up if that fails as well. This makes sure we return some entropy and become spec compliant. Signed-off-by: Andre Przywara Reported-by: Sami Mujawar --- virtio/rng.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/virtio/rng.c b/virtio/rng.c index e6e70ced3..d5959d358 100644 --- a/virtio/rng.c +++ b/virtio/rng.c @@ -66,8 +66,18 @@ static bool virtio_rng_do_io_request(struct kvm *kvm, struct rng_dev *rdev, stru head = virt_queue__get_iov(queue, iov, &out, &in, kvm); len = readv(rdev->fd, iov, in); - if (len < 0 && errno == EAGAIN) - len = 0; + if (len < 0 && (errno == EAGAIN || errno == EINTR)) { + /* + * The virtio 1.0 spec demands at least one byte of entropy, + * so we cannot just return with 0 if something goes wrong. + * The urandom(4) manpage mentions that a read from /dev/urandom + * should always return at least 256 bytes of randomness, so + * just retry here in case we were interrupted by a signal. + */ + len = readv(rdev->fd, iov, in); + if (len < 1) + return false; + } virt_queue__set_used_elem(queue, head, len);