From mboxrd@z Thu Jan 1 00:00:00 1970 From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) Subject: bug#31268: 'guix system vm-image' hangs Date: Tue, 22 May 2018 18:23:35 +0200 Message-ID: <87h8mz4q2g.fsf@gnu.org> References: <87604en3u5.fsf@gmail.com> <20180425223706.22d91e40@centurylink.net> <877eoua9v1.fsf@gmail.com> <87r2mxw1ax.fsf@netris.org> <87bme0ydzn.fsf@gnu.org> <87y3h4fy8c.fsf@netris.org> <87muwx9h82.fsf@lassieur.org> <87a7swrk8i.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:46920) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fLA5y-0004AK-DX for bug-guix@gnu.org; Tue, 22 May 2018 12:25:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fLA5v-0004iy-1d for bug-guix@gnu.org; Tue, 22 May 2018 12:25:06 -0400 Received: from debbugs.gnu.org ([208.118.235.43]:36452) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fLA5u-0004in-SE for bug-guix@gnu.org; Tue, 22 May 2018 12:25:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1fLA5u-0006iQ-IY for bug-guix@gnu.org; Tue, 22 May 2018 12:25:02 -0400 Sender: "Debbugs-submit" Resent-Message-ID: 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") List-Id: Bug reports for GNU Guix List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guix-bounces+gcggb-bug-guix=m.gmane.org@gnu.org Sender: "bug-Guix" To: =?UTF-8?Q?Cl=C3=A9ment?= Lassieur Cc: 31268@debbugs.gnu.org, George myglc2 Clemmer --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello! (+Cc: Leo for randomness input.) ludo@gnu.org (Ludovic Court=C3=A8s) skribis: > Cl=C3=A9ment Lassieur skribis: > >> Mark H Weaver 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 >> Date: Wed Apr 11 13:27:52 2018 -0400 >> >> random: fix crng_ready() test >>=20=20=20=20=20 >> commit 43838a23a05fbd13e47d750d3dfd77001536dd33 upstream. >>=20=20=20=20=20 >> The crng_init variable has three states: >>=20=20=20=20=20 >> 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. >>=20=20=20=20=20 >> 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 > =E2=80=98generate_random_uint32=E2=80=99, which in turn indirectly calls > =E2=80=98get_random_bytes=E2=80=99 from libuuid (package =E2=80=98e2fspro= gs=E2=80=99). And I suppose > that=E2=80=99s where it blocks, even though it=E2=80=99s supposed to be u= sing > /dev/urandom, which is not supposed to block. I was looking at the wrong code: we=E2=80=99re using libuuid from util-linu= x, which in turn uses getrandom(2). Since it doesn=E2=80=99t 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=E2=80=99s =E2=80=98uuid_generate=E2=80=99, which is good en= ough for this purpose. I=E2=80=99ll submit it upstream. 2. e2fsprogs is changed to use a libuuid that passes GRND_NONBLOCK. It does the job, but it=E2=80=99s quite inelegant. Another approach I looked at was to seed the VM=E2=80=99s PRNG from /dev/hw= rng, which I thought was connected to the host via =E2=80=98virtio-rng-pci=E2=80= =99, but I get ENODEV while trying to read from /dev/hwrng in the guest like this: --=-=-= Content-Type: text/x-patch Content-Disposition: inline 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))) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Am I missing something, Leo? In short, we=E2=80=99re almost done with this bug, now we just need to make= sure we have a reasonable fix. Thanks, Ludo=E2=80=99. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0003-gnu-e2fsprogs-Use-libuuid-with-non-blocking-random.patch >From 43357218f024b251fc2b741dc3e8bdc4c001051f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 22 May 2018 18:07:08 +0200 Subject: [PATCH 3/3] gnu: e2fsprogs: Use libuuid with non-blocking random. Partly fixes . * 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 + ;; . + (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: . + (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 . + +--- 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 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-gnu-parted-Use-weak-non-blocking-randomness-for-FAT-.patch >From 3110c594afb8839ba81b528f316b6d6dce757e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= 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 . * 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 . + +--- a/libparted/labels/misc.h ++++ b/libparted/labels/misc.h +@@ -17,7 +17,8 @@ + along with this program. If not, see . */ + + #include +-#include ++#include ++#include + + /* 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 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-vm-Use-a-deterministic-file-system-UUID-in-shared-st.patch >From 8aa37a4124db90a9991485477d1af85677c7fa1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= 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 . + ;; 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 --=-=-=--