From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Subject: bug#37501: [core-updates] Entropy starvation during boot Date: Thu, 03 Oct 2019 00:29:59 +0200 Message-ID: <87h84qdbmg.fsf@gnu.org> References: <87sgolae6l.fsf@devup.no> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:470:142:3::10]:44896) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFn9E-0000Ce-0f for bug-guix@gnu.org; Wed, 02 Oct 2019 18:31:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iFn9C-0002IV-6V for bug-guix@gnu.org; Wed, 02 Oct 2019 18:31:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:57892) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iFn9C-0002IP-1V for bug-guix@gnu.org; Wed, 02 Oct 2019 18:31:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1iFn9B-0003iC-Ru for bug-guix@gnu.org; Wed, 02 Oct 2019 18:31:01 -0400 Sender: "Debbugs-submit" Resent-Message-ID: In-Reply-To: <87sgolae6l.fsf@devup.no> (Marius Bakke's message of "Tue, 24 Sep 2019 17:48:02 +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: Marius Bakke Cc: 37501@debbugs.gnu.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi again, Marius Bakke skribis: > After reconfiguring on the 'core-updates' branch, systems using the > OpenSSH service will occasionally (not always!) hang forever during > boot, waiting for entropy. Moving the mouse or mashing the keyboard > allows the boot to proceed. > > I don't think this is limited to OpenSSH, but anything that calls > getrandom() during startup. > > There is some information about this problem and various workarounds > here, including links to recent LKML discussions: > > https://daniel-lange.com/archives/152-hello-buster.html I read some of these, and our =E2=80=98urandom-seed-service-type=E2=80=99 h= as the same bug as . Namely, we write the previous seed to /dev/urandom but we don=E2=80=99t credit the entropy. The attached patch fixes that, and I think it should fix the problem you reported. Could people give it a try? I=E2=80=99m interested in seeing the value of /proc/sys/kernel/random/entropy_avail with and without this patch right after boot (don=E2=80=99t try it in =E2=80=98guix system vm=E2=80=99 becaus= e there=E2=80=99s no seed there.) I wasn=E2=80=99t sure how much to add to the entropy count, but I think it= =E2=80=99s safe to account for all the bits of the seed since we know that it comes from /dev/urandom. Thoughts? Ludo=E2=80=99. --=-=-= Content-Type: text/x-patch Content-Disposition: inline diff --git a/gnu/services/base.scm b/gnu/services/base.scm index 25716ef152..3fe5cb3329 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -573,7 +573,13 @@ file systems, as well as corresponding @file{/etc/fstab} entries."))) (lambda (seed) (call-with-output-file "/dev/urandom" (lambda (urandom) - (dump-port seed urandom)))))) + (dump-port seed urandom) + + ;; Writing SEED to URANDOM isn't enough: we must + ;; also tell the kernel to account for these + ;; extra bits of entropy. + (let ((bits (* 8 (stat:size (stat seed))))) + (add-to-entropy-count urandom bits))))))) ;; Try writing from /dev/hwrng into /dev/urandom. ;; It seems that the file /dev/hwrng always exists, even diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm index f2fdb4d9d1..bbf2531c79 100644 --- a/guix/build/syscalls.scm +++ b/guix/build/syscalls.scm @@ -68,6 +68,7 @@ statfs free-disk-space device-in-use? + add-to-entropy-count processes mkdtemp! @@ -706,6 +707,33 @@ backend device." (list (strerror err)) (list err)))))) + +;;; +;;; Random. +;;; + +;; From . +(define RNDADDTOENTCNT #x40045201) + +(define (add-to-entropy-count port-or-fd n) + "Add N to the kernel's entropy count (the value that can be read from +/proc/sys/kernel/random/entropy_avail). PORT-OR-FD must correspond to +/dev/urandom or /dev/random. Raise to 'system-error with EPERM when the +caller lacks root privileges." + (let ((fd (if (port? port-or-fd) + (fileno port-or-fd) + port-or-fd)) + (box (make-bytevector (sizeof int)))) + (bytevector-sint-set! box 0 n (native-endianness) + (sizeof int)) + (let-values (((ret err) + (%ioctl fd RNDADDTOENTCNT + (bytevector->pointer box)))) + (unless (zero? err) + (throw 'system-error "add-to-entropy-count" "~A" + (list (strerror err)) + (list err)))))) + ;;; ;;; Containers. diff --git a/tests/syscalls.scm b/tests/syscalls.scm index eeb223b950..1b3121e503 100644 --- a/tests/syscalls.scm +++ b/tests/syscalls.scm @@ -567,6 +567,19 @@ (let ((result (call-with-input-file "/var/run/utmpx" read-utmpx))) (or (utmpx? result) (eof-object? result)))) +(when (zero? (getuid)) + (test-skip 1)) +(test-equal "add-to-entropy-count" + EPERM + (call-with-output-file "/dev/urandom" + (lambda (port) + (catch 'system-error + (lambda () + (add-to-entropy-count port 77) + #f) + (lambda args + (system-error-errno args)))))) + (test-end) (false-if-exception (delete-file temp-file)) --=-=-=--