From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id GMxsBJMCUGJm1QAAgWs5BA (envelope-from ) for ; Fri, 08 Apr 2022 11:38:27 +0200 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id WKkMAZMCUGIdIAEAauVa8A (envelope-from ) for ; Fri, 08 Apr 2022 11:38:27 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id D44643A643 for ; Fri, 8 Apr 2022 11:38:25 +0200 (CEST) Received: from localhost ([::1]:60940 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ncl4S-00086E-Kh for larch@yhetil.org; Fri, 08 Apr 2022 05:38:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39192) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nckzI-0005Xs-Im for bug-guix@gnu.org; Fri, 08 Apr 2022 05:33:04 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:40067) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nckzG-0001rQ-5P for bug-guix@gnu.org; Fri, 08 Apr 2022 05:33:04 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1nckzG-0003eM-1h for bug-guix@gnu.org; Fri, 08 Apr 2022 05:33:02 -0400 X-Loop: help-debbugs@gnu.org Subject: bug#54770: Non-root LUKS devices unusable after Shepherd upgrade Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: bug-guix@gnu.org Resent-Date: Fri, 08 Apr 2022 09:33:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 54770 X-GNU-PR-Package: guix X-GNU-PR-Keywords: To: 54770@debbugs.gnu.org Received: via spool by 54770-submit@debbugs.gnu.org id=B54770.164941035413997 (code B ref 54770); Fri, 08 Apr 2022 09:33:02 +0000 Received: (at 54770) by debbugs.gnu.org; 8 Apr 2022 09:32:34 +0000 Received: from localhost ([127.0.0.1]:33964 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nckyk-0003dc-Kn for submit@debbugs.gnu.org; Fri, 08 Apr 2022 05:32:34 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45750) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nckyi-0003dO-Qh for 54770@debbugs.gnu.org; Fri, 08 Apr 2022 05:32:29 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:37572) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nckyd-0001od-FH for 54770@debbugs.gnu.org; Fri, 08 Apr 2022 05:32:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:In-Reply-To:Date:References:Subject:To: From; bh=gMcXDZnXd+Ym2Vds85fzW/b0OX2Qv53iBDW1GEN12wk=; b=jeW2/BatYdwKSHjQ1DBR 9cOcvW9NMZY1Q3/89t0E5XWN3ixiuhGEvAC356cEsCyzEQU+ycdu+S1mxcrKX5PBcxeoxm2mrQBcy SR+ZK3WzF+WwPaK+vm4nCgDUb/ChRdiaAwdtwwKypH+I7dj1mb5j9jbMrcCqKUFoUXuQsNxKpFBJu USr5hVrxuXQM4K0VEjpH4YKk8dHfmBzKCgLBjz35qv2GxZWDc23WnkN+D/2JPozzzirDv7SVJoxuO PFkq8aNktMuhcOyP2rIgvwPzFikcYnuYJeSj7kqNDBV3yT3tln5axIGfu4lCgkr7JvOJqfmBgi3hS w/4anyOagxbIsQ==; Received: from [193.50.110.136] (port=50052 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nckya-0007qS-0L for 54770@debbugs.gnu.org; Fri, 08 Apr 2022 05:32:23 -0400 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= References: <87r168etvd.fsf@inria.fr> Date: Fri, 08 Apr 2022 11:32:17 +0200 In-Reply-To: <87r168etvd.fsf@inria.fr> ("Ludovic =?UTF-8?Q?Court=C3=A8s?="'s message of "Thu, 07 Apr 2022 18:33:10 +0200") Message-ID: <87mtgvdiou.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-guix@gnu.org List-Id: Bug reports for GNU Guix List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guix-bounces+larch=yhetil.org@gnu.org Sender: "bug-Guix" X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1649410706; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:resent-cc:resent-from:resent-sender: resent-message-id:in-reply-to:in-reply-to:references:references: list-id:list-help:list-unsubscribe:list-subscribe:list-post: dkim-signature; bh=gMcXDZnXd+Ym2Vds85fzW/b0OX2Qv53iBDW1GEN12wk=; b=AZRGvI75ggbkuxPBUB7vEZuFFNg92CDvzLuIaiuO7NuMY+60+a+aG8lNbEFb8NjLwDUwzG KarhcTzLkixpfKEb6AQDhi80sGprO8nWIpTmLBSrYKtM1i5acLpzowGsqUxjPpqvZ2UC2F JG6v0lXZbCZLzyTJGDNXYDVxQU5gvzIUvfQyYr5SuEsIrgZsBRQmaflWdtN4tBpa1ycisV byozFWi7JKgq0qJD4UqvTIXnZxlTPdtYFKXRqDUZCXdWb6z57oGrsw819092Tn/W741MTa 7flBD77knYHkjZMLrVf1rbuJoSVJS4lrzpM1osF4+Huur5BZzfLnTvcLC7SVMQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1649410706; a=rsa-sha256; cv=none; b=njzWbg4a6Lk/YBz4kNQNFNFDn35DCvtzgT2pEsfYqnzbrWxeRF9Fy0bMPo+FFBLOkz0mMJ v7agx3dcepiH5j5F6MGiLTxT7FmxMrnLw4KBFhB552WQPTeAT/LsdktStg4AyYxDMZR+5g rLEh/fGVbn531FNv6N2FM1ikLebNR1HvqtSd2E5vYPqvVCLyFARmVmyD70I0RE54A8EJPN lCGEQf5BN+ip56gav4TAV+6IDjP9vWLLgo8o1QRQjgtPrCUWV+seRJdF3gv/Cb5aEfbuFx oxzJqG2EGNa6fGJtqQyDIwSS0A9eit3v1Q/p1S4HRcfT1fMbAIWgO8IsfJJqgQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gnu.org header.s=fencepost-gnu-org header.b="jeW2/Bat"; dmarc=pass (policy=none) header.from=gnu.org; spf=pass (aspmx1.migadu.com: domain of "bug-guix-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="bug-guix-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -4.67 Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gnu.org header.s=fencepost-gnu-org header.b="jeW2/Bat"; dmarc=pass (policy=none) header.from=gnu.org; spf=pass (aspmx1.migadu.com: domain of "bug-guix-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="bug-guix-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: D44643A643 X-Spam-Score: -4.67 X-Migadu-Scanner: scn0.migadu.com X-TUID: pk0pT/GPGaTu --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi, Ludovic Court=C3=A8s skribis: > Following the Shepherd upgrade in commit > 400c9ed3d779308e56038305d40cd93acb496180, attempts to open non-root LUKS > devices from a Shepherd service fail with this cryptsetup message: > > Nothing to read on input. > > This is because standard input is now /dev/null so it cannot read the > passphrase. In Cryptsetup, the =E2=80=98tools_get_key=E2=80=99 function reads this: --8<---------------cut here---------------start------------->8--- if (tools_is_stdin(key_file)) { if (isatty(STDIN_FILENO)) { if (keyfile_offset) { log_err(_("Cannot use offset with terminal input.")= ); } else { if (!prompt && !crypt_get_device_name(cd)) snprintf(tmp, sizeof(tmp), _("Enter passphr= ase: ")); else if (!prompt) { backing_file =3D crypt_loop_backing_file(cr= ypt_get_device_name(cd)); snprintf(tmp, sizeof(tmp), _("Enter passphr= ase for %s: "), backing_file ?: crypt_get_device_name(cd)); free(backing_file); } r =3D crypt_get_key_tty(prompt ?: tmp, key, key_siz= e, timeout, verify, cd); } } else { log_dbg("STDIN descriptor passphrase entry requested."); /* No keyfile means STDIN with EOL handling (\n will end in= put)). */ r =3D crypt_keyfile_device_read(cd, NULL, key, key_size, keyfile_offset, keyfile_size_max, key_file ? 0 : CRYPT_KEYFILE_STOP_EOL); } } --8<---------------cut here---------------end--------------->8--- isatty(3) would return 0 when stdin is /dev/null; simply binding stdin to /dev/console: (with-input-from-file "/dev/console" (lambda () (system* "cryptsetup" =E2=80=A6))) wouldn=E2=80=99t help, for reasons that are less clear to me=C2=B9. The attached patch solves the =E2=80=98cryptsetup open=E2=80=99 problem for= the case when =E2=80=98cryptsetup=E2=80=99 is invoked from shepherd=E2=80=94e.g., fo= r an encrypted /home. I=E2=80=99m now running the =E2=80=9Cencrypted-root-os=E2=80=9D test. I=E2=80=99m not sure how to test fsck interactivity though; ideas welcome. = If you=E2=80=99re reading this and would like to test it on the bare metal (wo= rst case is it fails to boot and you have to reboot into the older generation), that=E2=80=99s also much appreciated. Feedback welcome! Thanks, Ludo=E2=80=99. =C2=B9 This returns true: sudo strace -f -o ,,s guile -c '(with-input-from-file "/dev/console" (lam= bda () (system* "guile" "-c" "(pk (isatty? (current-input-port)))")))' --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm index d95340df83..b06a4cc25c 100644 --- a/gnu/build/file-systems.scm +++ b/gnu/build/file-systems.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright =C2=A9 2014, 2015, 2016, 2017, 2018, 2020, 2021 Ludovic Cour= t=C3=A8s +;;; Copyright =C2=A9 2014-2018, 2020-2022 Ludovic Court=C3=A8s ;;; Copyright =C2=A9 2016, 2017 David Craven ;;; Copyright =C2=A9 2017 Mathieu Othacehe ;;; Copyright =C2=A9 2019 Guillaume Le Vaillant @@ -54,6 +54,7 @@ (define-module (gnu build file-systems) =20 bind-mount =20 + system*/tty mount-flags->bit-mask check-file-system mount-file-system @@ -67,6 +68,33 @@ (define-module (gnu build file-systems) ;;; ;;; Code: =20 +(define (system*/console program . args) + "Run PROGRAM with ARGS in a tty on top of /dev/console. The return valu= e is +as for 'system*'." + (match (primitive-fork) + (0 + (dynamic-wind + (const #t) + (lambda () + (login-tty (open-fdes "/dev/console" O_RDWR)) + (apply execlp program program args)) + (lambda () + (primitive-_exit 127)))) + (pid + (cdr (waitpid pid))))) + +(define (system*/tty program . args) + "Run PROGRAM with ARGS, creating a tty if its standard input isn't one. +The return value is as for 'system*'. + +This is necessary for commands such as 'cryptsetup open' or 'fsck' that may +need to interact with the user but might be invoked from shepherd, where +standard input is /dev/null." + (apply (if (isatty? (current-input-port)) + system* + system*/console) + program args)) + (define (bind-mount source target) "Bind-mount SOURCE at TARGET." (mount source target "" MS_BIND)) @@ -180,13 +208,13 @@ (define (check-ext2-file-system device force? repair) do not write to the file system to fix errors. If it's #t, fix all errors. Otherwise, fix only those considered safe to repair automatically= ." (match (status:exit-val - (apply system* `("e2fsck" "-v" "-C" "0" - ,@(if force? '("-f") '()) - ,@(match repair - (#f '("-n")) - (#t '("-y")) - (_ '("-p"))) - ,device))) + (apply system*/tty "e2fsck" "-v" "-C" "0" + `(,@(if force? '("-f") '()) + ,@(match repair + (#f '("-n")) + (#t '("-y")) + (_ '("-p"))) + ,device))) (0 'pass) (1 'errors-corrected) (2 'reboot-required) @@ -312,14 +340,14 @@ (define (check-bcachefs-file-system device force? rep= air) (status ;; A number, or #f on abnormal termination (e.g., assertion failu= re). (status:exit-val - (apply system* `("bcachefs" "fsck" "-v" - ,@(if force? '("-f") '()) - ,@(match repair - (#f '("-n")) - (#t '("-y")) - (_ '("-p"))) - ;; Make each multi-device member a separate arg= ument. - ,@(string-split device #\:)))))) + (apply system*/tty "bcachefs" "fsck" "-v" + `(,@(if force? '("-f") '()) + ,@(match repair + (#f '("-n")) + (#t '("-y")) + (_ '("-p"))) + ;; Make each multi-device member a separate argument. + ,@(string-split device #\:)))))) (match (and=3D> status (cut logand <> (lognot ignored-bits))) (0 'pass) (1 'errors-corrected) @@ -364,17 +392,17 @@ (define (check-btrfs-file-system device force? repair) fix only those considered safe to repair automatically." (if force? (match (status:exit-val - (apply system* `("btrfs" "check" "--progress" - ;; Btrfs's =E2=80=98--force=E2=80=99 is not= relevant to us here. - ,@(match repair - ;; Upstream considers ALL repairs dange= rous - ;; and will warn the user at run time. - (#t '("--repair")) - (_ '("--readonly" ; a no-op for clarity - ;; A 466G file system with 180G u= sed is - ;; enough to kill btrfs with 6G o= f RAM. - "--mode" "lowmem"))) - ,device))) + (apply system*/tty "btrfs" "check" "--progress" + ;; Btrfs's =E2=80=98--force=E2=80=99 is not relevant = to us here. + `(,@(match repair + ;; Upstream considers ALL repairs dangerous + ;; and will warn the user at run time. + (#t '("--repair")) + (_ '("--readonly" ; a no-op for clarity + ;; A 466G file system with 180G used is + ;; enough to kill btrfs with 6G of RAM. + "--mode" "lowmem"))) + ,device))) (0 'pass) (_ 'fatal-error)) 'pass)) @@ -412,11 +440,11 @@ (define (check-fat-file-system device force? repair) not write to the file system to fix errors. Otherwise, automatically fix t= hem using the least destructive approach." (match (status:exit-val - (apply system* `("fsck.vfat" "-v" - ,@(match repair - (#f '("-n")) - (_ '("-a"))) ; no 'safe/#t distinction - ,device))) + (system*/tty "fsck.vfat" "-v" + (match repair + (#f "-n") + (_ "-a")) ;no 'safe/#t distinction + device)) (0 'pass) (1 'errors-corrected) (_ 'fatal-error))) @@ -545,7 +573,7 @@ (define (check-jfs-file-system device force? repair) only if FORCE? is true. Otherwise, replay the transaction log before chec= king and automatically fix found errors." (match (status:exit-val - (apply system* + (apply system*/tty `("jfs_fsck" "-v" ;; The =E2=80=98LEVEL=E2=80=99 logic is convoluted. To= quote fsck/xchkdsk.c ;; (=E2=80=98-p=E2=80=99, =E2=80=98-a=E2=80=99, and =E2= =80=98-r=E2=80=99 are aliases in every way): @@ -621,10 +649,10 @@ (define (check-f2fs-file-system device force? repair) "warning: forced check of F2FS ~a implies repairing any errors= ~%" device)) (match (status:exit-val - (apply system* `("fsck.f2fs" - ,@(if force? '("-f") '()) - ,@(if repair '("-p") '("--dry-run")) - ,device))) + (apply system*/tty "fsck.f2fs" + `(,@(if force? '("-f") '()) + ,@(if repair '("-p") '("--dry-run")) + ,device))) ;; 0 and -1 are the only two possibilities according to the man page. (0 'pass) (_ 'fatal-error))) @@ -709,9 +737,9 @@ (define (check-ntfs-file-system device force? repair) true and the volume has been repaired by an external tool, clear the volume dirty flag to indicate that it's now safe to mount." (match (status:exit-val - (apply system* `("ntfsfix" - ,@(if repair '("--clear-dirty") '("--no-action"= )) - ,device))) + (system*/tty "ntfsfix" + (if repair "--clear-dirty" "--no-action") + device)) (0 'pass) (_ 'fatal-error))) =20 @@ -754,11 +782,11 @@ (define (check-xfs-file-system device force? repair) Otherwise, only replay the log, and check without attempting further repai= rs." (define (xfs_repair) (status:exit-val - (apply system* `("xfs_repair" "-Pv" - ,@(match repair - (#t '("-e")) - (_ '("-n"))) ; will miss some errors - ,device)))) + (system*/tty "xfs_repair" "-Pv" + (match repair + (#t "-e") + (_ "-n")) ;will miss some errors + device))) (if force? ;; xfs_repair fails with exit status 2 if the log is dirty, which is ;; likely in situations where you're running xfs_repair. Only the k= ernel diff --git a/gnu/system/mapped-devices.scm b/gnu/system/mapped-devices.scm index 96a381d5fe..e6b8970c12 100644 --- a/gnu/system/mapped-devices.scm +++ b/gnu/system/mapped-devices.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright =C2=A9 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovi= c Court=C3=A8s +;;; Copyright =C2=A9 2014-2022 Ludovic Court=C3=A8s ;;; Copyright =C2=A9 2016 Andreas Enge ;;; Copyright =C2=A9 2017, 2018 Mark H Weaver ;;; @@ -202,7 +202,8 @@ (define (open-luks-device source targets) ;; XXX: 'use-modules' should be at the top level. (use-modules (rnrs bytevectors) ;bytevector? ((gnu build file-systems) - #:select (find-partition-by-luks-uuid)) + #:select (find-partition-by-luks-uuid + system*/tty)) ((guix build utils) #:select (mkdir-p))) =20 ;; Create '/run/cryptsetup/' if it does not exist, as device lo= cking @@ -211,28 +212,32 @@ (define (open-luks-device source targets) =20 ;; Use 'cryptsetup-static', not 'cryptsetup', to avoid pulling = the ;; whole world inside the initrd (for when we're in an initrd). - (zero? (system* #$(file-append cryptsetup-static "/sbin/cryptse= tup") - "open" "--type" "luks" + ;; 'cryptsetup open' requires standard input to be a tty to all= ow + ;; for interaction but shepherd sets standard input to /dev/nul= l; + ;; thus, explicitly request a tty. + (zero? (system*/tty + #$(file-append cryptsetup-static "/sbin/cryptsetup") + "open" "--type" "luks" =20 - ;; Note: We cannot use the "UUID=3Dsource" synt= ax here - ;; because 'cryptsetup' implements it by search= ing the - ;; udev-populated /dev/disk/by-id directory but= udev may - ;; be unavailable at the time we run this. - (if (bytevector? source) - (or (let loop ((tries-left 10)) - (and (positive? tries-left) - (or (find-partition-by-luks-uuid= source) - ;; If the underlying partiti= on is - ;; not found, try again after - ;; waiting a second, up to t= en - ;; times. FIXME: This shoul= d be - ;; dealt with in a more robu= st way. - (begin (sleep 1) - (loop (- tries-left 1= )))))) - (error "LUKS partition not found" sourc= e)) - source) + ;; Note: We cannot use the "UUID=3Dsource" syntax here + ;; because 'cryptsetup' implements it by searching the + ;; udev-populated /dev/disk/by-id directory but udev may + ;; be unavailable at the time we run this. + (if (bytevector? source) + (or (let loop ((tries-left 10)) + (and (positive? tries-left) + (or (find-partition-by-luks-uuid source) + ;; If the underlying partition is + ;; not found, try again after + ;; waiting a second, up to ten + ;; times. FIXME: This should be + ;; dealt with in a more robust way. + (begin (sleep 1) + (loop (- tries-left 1)))))) + (error "LUKS partition not found" source)) + source) =20 - #$target))))))) + #$target))))))) =20 (define (close-luks-device source targets) "Return a gexp that closes TARGET, a LUKS device." --=-=-=--