From: ludo@gnu.org (Ludovic Courtès)
To: "Clément Lassieur" <clement@lassieur.org>
Cc: 31268@debbugs.gnu.org, George myglc2 Clemmer <myglc2@gmail.com>
Subject: bug#31268: 'guix system vm-image' hangs
Date: Tue, 22 May 2018 18:23:35 +0200 [thread overview]
Message-ID: <87h8mz4q2g.fsf@gnu.org> (raw)
In-Reply-To: <87a7swrk8i.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Fri, 18 May 2018 18:39:41 +0200")
[-- Attachment #1: Type: text/plain, Size: 2434 bytes --]
Hello!
(+Cc: Leo for randomness input.)
ludo@gnu.org (Ludovic Courtès) skribis:
> Clément Lassieur <clement@lassieur.org> skribis:
>
>> Mark H Weaver <mhw@netris.org> writes:
>
> [...]
>
>>> I suggest doing a git bisect on the 4.16.y branch of the linux-stable
>>> git repository, between the 4.16.3 and 4.16.4 tags.
>>
>> I did it, here is the result:
>
> Impressive, thanks a lot! Did you have a script to do that or
> something?
>
>> cd8d7a5778a4abf76ee8fe8f1bfcf78976029f8d is the first bad commit
>> commit cd8d7a5778a4abf76ee8fe8f1bfcf78976029f8d
>> Author: Theodore Ts'o <tytso@mit.edu>
>> Date: Wed Apr 11 13:27:52 2018 -0400
>>
>> random: fix crng_ready() test
>>
>> commit 43838a23a05fbd13e47d750d3dfd77001536dd33 upstream.
>>
>> The crng_init variable has three states:
>>
>> 0: The CRNG is not initialized at all
>> 1: The CRNG has a small amount of entropy, hopefully good enough for
>> early-boot, non-cryptographical use cases
>> 2: The CRNG is fully initialized and we are sure it is safe for
>> cryptographic use cases.
>>
>> The crng_ready() function should only return true once we are in the
>> last state. This addresses CVE-2018-1108.
>
> What happens I think is that libparted/fs/r/fat/fat.c:fat_create calls
> ‘generate_random_uint32’, which in turn indirectly calls
> ‘get_random_bytes’ from libuuid (package ‘e2fsprogs’). And I suppose
> that’s where it blocks, even though it’s supposed to be using
> /dev/urandom, which is not supposed to block.
I was looking at the wrong code: we’re using libuuid from util-linux,
which in turn uses getrandom(2). Since it doesn’t pass the
GRND_NONBLOCK flag, it ends up blocking forever because too little
entropy is available in the VM.
The following patches work around that:
1. Parted now explicitly uses getrandom(2) with GRND_NONBLOCK instead
of libuuid’s ‘uuid_generate’, which is good enough for this
purpose. I’ll submit it upstream.
2. e2fsprogs is changed to use a libuuid that passes GRND_NONBLOCK.
It does the job, but it’s quite inelegant.
Another approach I looked at was to seed the VM’s PRNG from /dev/hwrng,
which I thought was connected to the host via ‘virtio-rng-pci’, but I
get ENODEV while trying to read from /dev/hwrng in the guest like this:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 1008 bytes --]
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index b6561dfc7..3bfd6b4ca 100644
--- a/gnu/system/vm.scm
+++ b/gnu/system/vm.scm
@@ -319,6 +319,18 @@ the image."
(set-path-environment-variable "PATH" '("bin" "sbin") inputs)
+ ;; Try writing from /dev/hwrng into /dev/urandom.
+ ;; It seems that the file /dev/hwrng always exists, even
+ ;; when there is no hardware random number generator
+ ;; available. So, we handle a failed read or any other error
+ ;; reported by the operating system.
+ (let ((buf (call-with-input-file "/dev/hwrng"
+ (lambda (hwrng)
+ (get-bytevector-n hwrng 512)))))
+ (call-with-output-file "/dev/urandom"
+ (lambda (urandom)
+ (put-bytevector urandom buf))))
+
(let* ((graphs '#$(match inputs
(((names . _) ...)
names)))
[-- Attachment #3: Type: text/plain, Size: 160 bytes --]
Am I missing something, Leo?
In short, we’re almost done with this bug, now we just need to make sure
we have a reasonable fix.
Thanks,
Ludo’.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-gnu-e2fsprogs-Use-libuuid-with-non-blocking-random.patch --]
[-- Type: text/x-patch, Size: 3009 bytes --]
From 43357218f024b251fc2b741dc3e8bdc4c001051f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
Date: Tue, 22 May 2018 18:07:08 +0200
Subject: [PATCH 3/3] gnu: e2fsprogs: Use libuuid with non-blocking random.
Partly fixes <https://bugs.gnu.org/31268>.
* gnu/packages/linux.scm (util-linux/libuuid-non-blocking-random): New
variable.
(e2fsprogs)[inputs]: Use it instead of UTIL-LINUX.
---
gnu/packages/linux.scm | 17 ++++++++++++++++-
...util-linux-libuuid-non-blocking-random.patch | 15 +++++++++++++++
2 files changed, 31 insertions(+), 1 deletion(-)
create mode 100644 gnu/packages/patches/util-linux-libuuid-non-blocking-random.patch
diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index bb4e00394..c93947e68 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -671,6 +671,20 @@ block devices, UUIDs, TTYs, and many other tools.")
(append (origin-patches (package-source util-linux))
(search-patches "util-linux-CVE-2018-7738.patch")))))))
+(define-public util-linux/libuuid-non-blocking-random
+ ;; Package variant where libuuid uses non-blocking (weak) random. See
+ ;; <https://bugs.gnu.org/31268>.
+ (package
+ (inherit util-linux)
+ (name "util-linux-weak-random")
+ (source (let ((source (package-source util-linux)))
+ (origin
+ (inherit source)
+ (patches (append (search-patches
+ "util-linux-libuuid-non-blocking-random.patch")
+ (origin-patches source))))))
+ (properties '((hidden? . #t)))))
+
(define-public ddate
(package
(name "ddate")
@@ -779,7 +793,8 @@ slabtop, and skill.")
(base32
"00ilv65dzcgiap435j89xk86shf7rrav3wsik7cahy789qijdcn9"))))
(build-system gnu-build-system)
- (inputs `(("util-linux" ,util-linux)))
+ ;; Arrange so that 'mke2fs' doesn't wait: <https://bugs.gnu.org/31268>.
+ (inputs `(("util-linux" ,util-linux/libuuid-non-blocking-random)))
(native-inputs `(("pkg-config" ,pkg-config)
("texinfo" ,texinfo) ;for the libext2fs Info manual
diff --git a/gnu/packages/patches/util-linux-libuuid-non-blocking-random.patch b/gnu/packages/patches/util-linux-libuuid-non-blocking-random.patch
new file mode 100644
index 000000000..c0b3ea24d
--- /dev/null
+++ b/gnu/packages/patches/util-linux-libuuid-non-blocking-random.patch
@@ -0,0 +1,15 @@
+Change libuuid so that 'uuid_generate' is non-blocking. This is needed when
+'mke2fs' is used during early boot in VMs with little entropy available.
+See <https://bugs.gnu.org/31268>.
+
+--- a/lib/randutils.c
++++ b/lib/randutils.c
+@@ -104,7 +104,7 @@ void random_get_bytes(void *buf, size_t nbytes)
+ int x;
+
+ errno = 0;
+- x = getrandom(cp, n, 0);
++ x = getrandom(cp, n, GRND_NONBLOCK);
+ if (x > 0) { /* success */
+ n -= x;
+ cp += x;
--
2.17.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0001-gnu-parted-Use-weak-non-blocking-randomness-for-FAT-.patch --]
[-- Type: text/x-patch, Size: 3406 bytes --]
From 3110c594afb8839ba81b528f316b6d6dce757e99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
Date: Tue, 22 May 2018 17:34:47 +0200
Subject: [PATCH 1/3] gnu: parted: Use weak (non-blocking) randomness for FAT
serial numbers.
Partly fixes <https://bugs.gnu.org/31268>.
* gnu/packages/patches/parted-non-blocking-random.patch: New file.
* gnu/packages/disk.scm (parted)[source]: Use it.
* gnu/local.mk (dist_patch_DATA): Add it.
---
gnu/local.mk | 1 +
gnu/packages/disk.scm | 3 +-
.../patches/parted-non-blocking-random.patch | 39 +++++++++++++++++++
3 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 gnu/packages/patches/parted-non-blocking-random.patch
diff --git a/gnu/local.mk b/gnu/local.mk
index 20975306b..4222050b5 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -975,6 +975,7 @@ dist_patch_DATA = \
%D%/packages/patches/p7zip-CVE-2017-17969.patch \
%D%/packages/patches/p7zip-remove-unused-code.patch \
%D%/packages/patches/password-store-gnupg-compat.patch \
+ %D%/packages/patches/parted-non-blocking-random.patch \
%D%/packages/patches/patchelf-page-size.patch \
%D%/packages/patches/patchelf-rework-for-arm.patch \
%D%/packages/patches/patchutils-xfail-gendiff-tests.patch \
diff --git a/gnu/packages/disk.scm b/gnu/packages/disk.scm
index d7bf72683..476b26acb 100644
--- a/gnu/packages/disk.scm
+++ b/gnu/packages/disk.scm
@@ -65,7 +65,8 @@
version ".tar.xz"))
(sha256
(base32
- "1r3qpg3bhz37mgvp9chsaa3k0csby3vayfvz8ggsqz194af5i2w5"))))
+ "1r3qpg3bhz37mgvp9chsaa3k0csby3vayfvz8ggsqz194af5i2w5"))
+ (patches (search-patches "parted-non-blocking-random.patch"))))
(build-system gnu-build-system)
(arguments
`(#:phases
diff --git a/gnu/packages/patches/parted-non-blocking-random.patch b/gnu/packages/patches/parted-non-blocking-random.patch
new file mode 100644
index 000000000..e30d9f413
--- /dev/null
+++ b/gnu/packages/patches/parted-non-blocking-random.patch
@@ -0,0 +1,39 @@
+Explicitly use a non-blocking random primitive. This is used primarily
+to compute FAT "serial numbers" in libparted/fs/r/fat/fat.c:fat_create,
+for which GRND_NONBLOCK is probably good enough.
+
+Assume the running kernel does support 'getrandom', which is the case on
+GuixSD. See <https://bugs.gnu.org/31268>.
+
+--- a/libparted/labels/misc.h
++++ b/libparted/labels/misc.h
+@@ -17,7 +17,8 @@
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+ #include <inttypes.h>
+-#include <uuid/uuid.h>
++#include <sys/random.h>
++#include <errno.h>
+
+ /* hack: use the ext2 uuid library to generate a reasonably random (hopefully
+ * with /dev/random) number. Unfortunately, we can only use 4 bytes of it.
+@@ -28,11 +29,17 @@ static inline uint32_t
+ generate_random_uint32 (void)
+ {
+ union {
+- uuid_t uuid;
++ char uuid[4];
+ uint32_t i;
+ } uu32;
++ ssize_t ret;
+
+- uuid_generate (uu32.uuid);
++ do
++ ret = getrandom (uu32.uuid, sizeof uu32, GRND_NONBLOCK);
++ while (ret == EAGAIN);
++
++ if (ret < sizeof uu32)
++ abort ();
+
+ return uu32.i > 0 ? uu32.i : 0xffffffff;
+ }
--
2.17.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0002-vm-Use-a-deterministic-file-system-UUID-in-shared-st.patch --]
[-- Type: text/x-patch, Size: 1769 bytes --]
From 8aa37a4124db90a9991485477d1af85677c7fa1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
Date: Tue, 22 May 2018 17:36:35 +0200
Subject: [PATCH 2/3] vm: Use a deterministic file system UUID in shared-store
VMs.
* gnu/system/vm.scm (system-qemu-image/shared-store): Pass
#:file-system-uuid to 'qemu-image'.
---
gnu/system/vm.scm | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index 09a11af86..b6561dfc7 100644
--- a/gnu/system/vm.scm
+++ b/gnu/system/vm.scm
@@ -752,6 +752,13 @@ with the host.
When FULL-BOOT? is true, return an image that does a complete boot sequence,
bootloaded included; thus, make a disk image that contains everything the
bootloader refers to: OS kernel, initrd, bootloader data, etc."
+ (define root-uuid
+ ;; Use a fixed UUID so that 'mke2fs' doesn't wait for strong randomness
+ ;; while generating a UUID. See <https://bugs.gnu.org/31268>.
+ ;; XXX: Actually it doesn't help since 'mke2fs' calls 'uuid_generate'
+ ;; anyway.
+ (operating-system-uuid os 'dce))
+
(mlet* %store-monad ((os-drv (operating-system-derivation os))
(bootcfg (operating-system-bootcfg os)))
;; XXX: When FULL-BOOT? is true, we end up creating an image that contains
@@ -763,6 +770,7 @@ bootloader refers to: OS kernel, initrd, bootloader data, etc."
#:bootloader (bootloader-configuration-bootloader
(operating-system-bootloader os))
#:disk-image-size disk-image-size
+ #:file-system-uuid root-uuid
#:inputs (if full-boot?
`(("bootcfg" ,bootcfg))
'())
--
2.17.0
next prev parent reply other threads:[~2018-05-22 16:25 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <87604en3u5.fsf@gmail.com>
[not found] ` <20180425223706.22d91e40@centurylink.net>
2018-04-26 4:07 ` 'guix system vm-image' hangs George myglc2 Clemmer
2018-04-26 14:09 ` bug#31268: " Ludovic Courtès
2018-04-30 8:23 ` Mark H Weaver
[not found] ` <87r2mxw1ax.fsf@netris.org>
2018-04-30 14:18 ` Ludovic Courtès
2018-04-30 16:36 ` Mark H Weaver
2018-05-18 14:22 ` Clément Lassieur
2018-05-18 16:39 ` Ludovic Courtès
2018-05-18 22:03 ` Clément Lassieur
2018-05-18 22:13 ` Ludovic Courtès
2018-05-22 16:23 ` Ludovic Courtès [this message]
2018-05-22 18:45 ` Efraim Flashner
2018-05-22 22:55 ` Mark H Weaver
2018-05-23 7:27 ` Ludovic Courtès
2018-05-23 8:23 ` Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://guix.gnu.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87h8mz4q2g.fsf@gnu.org \
--to=ludo@gnu.org \
--cc=31268@debbugs.gnu.org \
--cc=clement@lassieur.org \
--cc=myglc2@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).