NetBSD Problem Report #55157

From schaecsn@gmx.net  Thu Apr  9 04:19:30 2020
Return-Path: <schaecsn@gmx.net>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id A86651AEB87
	for <gnats-bugs@gnats.NetBSD.org>; Thu,  9 Apr 2020 04:19:30 +0000 (UTC)
Message-Id: <20200409041925.A98C38997A7@corona.crabdance.com>
Date: Wed,  8 Apr 2020 21:19:25 -0700 (PDT)
From: schaecsn@gmx.net
Reply-To: schaecsn@gmx.net
To: gnats-bugs@NetBSD.org
Subject: Request: cgd: timeout on waiting for passphrase
X-Send-Pr-Version: 3.95

>Number:         55157
>Category:       bin
>Synopsis:       Request: cgd: timeout on waiting for passphrase
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 09 04:20:00 +0000 2020
>Last-Modified:  Mon Apr 27 23:00:01 +0000 2020
>Originator:     schaecsn@gmx.net
>Release:        NetBSD 9.0
>Organization:
>Environment:
System: NetBSD XXX.XXX.XX 9.0 NetBSD 9.0 (GENERIC) #0: Fri=
 Feb 14 00:06:28 UTC 2020 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd=
64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
Every couple of months, we have here a blackout. When the ma=
chine comes back, /etc/rc.d/cgd waits on the passphrase prompt (in my case=
 for the home partition) and the whole bootup is blocked.

I rely on having remote access to my machine but can't ssh into it as ssh =
gets started after cgd. Had ssh started, I could ssh into the machine and =
manually mount the encrypted partition.

I have some patches that I use for some time. Perhaps they can serve as a =
starting point for a discussion.


I introduce a timeout flag for cgdconfig. A timeout can be configured in /=
etc/rc.conf via
cgd_flags=3D"-t 60"

In cgdconfig.c, it's hard to propagate a timeout value from main() all the=
 way to maybe_getpass(), where the timeout is applied and so the patch int=
roduces a global variable. This is similiar to the global variables nflag =
and pflag which are also derived from commandline arguments and set in mai=
n().

With my modified cgdconfig.c, /etc/rc.d/cgd times out and /dev/cgd* is lef=
t unconfigured. Cgdconfig and /etc/rc.d/cgd return an error as getpassfd()=
 can not distinguish a timeout from a wrong passphrase.

Now /etc/rc.d/fsck fails checking unconfigured encrypted filesystems and d=
rops into an emergency shell. For this I introduce a new fstab option "opt=
" which fsck will ignore if the partition is not configured:

- fsck happens to open /etc/fstab and retrieves options such as "opt". It =
does not know whether a partition is configured or not: it unconditionally=
 execv fsck.ffs
- fsck.ffs does not read /etc/fstab but knows (at some point) that the par=
tition is not configured.

Least intrusive way is to let fsck check for unconfigured partitions and s=
kip execv fsck.ffs if opt flag is set.

Next, mount_ffs does not like unknown options

# mount -a
mount_ffs: -o opt: option not supported

New options can to be introduced by extending /usr/include/mntopts.h

/* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */
...
#define MOPT_OPT                { "opt",        0, 0, 0 }
...

#define MOPT_FSTAB_COMPAT                                               \
...
        MOPT_OPT


I think cgd timeouts are important. What do you think about my patch? Anyo=
ne has ideas for a less intrusive implementation?

 Stefan

>How-To-Repeat:

>Fix:

Index: etc/defaults/rc.conf
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/etc/defaults/rc.conf,v
retrieving revision 1.151.2.1
diff -u -p -r1.151.2.1 rc.conf
=2D-- etc/defaults/rc.conf	27 Sep 2019 09:18:38 -0000	1.151.2.1
+++ etc/defaults/rc.conf	8 Apr 2020 23:36:17 -0000
@@ -116,7 +116,7 @@ raidframe=3DYES

 # Crypto file system.
 #
-cgd=3DYES
+cgd=3DYES			cgd_flags=3D""

 # Logical Volume Manager
 #
Index: etc/rc.d/cgd
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/etc/rc.d/cgd,v
retrieving revision 1.8
diff -u -p -r1.8 cgd
=2D-- etc/rc.d/cgd	1 Nov 2010 14:41:11 -0000	1.8
+++ etc/rc.d/cgd	8 Apr 2020 23:36:17 -0000
@@ -19,7 +19,7 @@ cgd_start()
 {
 	if [ -f /etc/cgd/cgd.conf ]; then
 		print_rc_normal "Configuring CGD devices."
-		cgdconfig -C
+		cgdconfig -C ${cgd_flags}
 	fi
 }

Index: include/mntopts.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/include/mntopts.h,v
retrieving revision 1.18
diff -u -p -r1.18 mntopts.h
=2D-- include/mntopts.h	9 Jan 2018 03:31:12 -0000	1.18
+++ include/mntopts.h	8 Apr 2020 23:36:45 -0000
@@ -77,12 +77,14 @@ struct mntopt {
 /* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */
 #define MOPT_AUTO		{ "auto",	0, 0, 0 }
 #define MOPT_RUMP		{ "rump",	0, 0, 0 }
+#define MOPT_OPT		{ "opt",	0, 0, 0 }
 #define MOPT_NULL		{ NULL,		0, 0, 0 }

 #define MOPT_FSTAB_COMPAT						\
 	MOPT_RO,							\
 	MOPT_RW,							\
-	MOPT_AUTO
+	MOPT_AUTO,							\
+	MOPT_OPT

 /* Standard options which all mounts can understand. */
 #define MOPT_STDOPTS							\
Index: sbin/cgdconfig/cgdconfig.8
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sbin/cgdconfig/cgdconfig.8,v
retrieving revision 1.44
diff -u -p -r1.44 cgdconfig.8
=2D-- sbin/cgdconfig/cgdconfig.8	29 Dec 2018 18:34:01 -0000	1.44
+++ sbin/cgdconfig/cgdconfig.8	8 Apr 2020 23:36:46 -0000
@@ -35,17 +35,20 @@
 .Nd configuration utility for the cryptographic disk driver
 .Sh SYNOPSIS
 .Nm
-.Op Fl enpv
+.Op Fl env
+.Op Fl p | Fl t Ar timeout
 .Op Fl V Ar vmeth
 .Ar cgd dev
 .Op Ar paramsfile
 .Nm
 .Fl C
-.Op Fl enpv
+.Op Fl env
+.Op Fl p | Fl t Ar timeout
 .Op Fl f Ar configfile
 .Nm
 .Fl G
-.Op Fl enpv
+.Op Fl env
+.Op Fl p | Fl t Ar timeout
 .Op Fl i Ar ivmeth
 .Op Fl k Ar kgmeth
 .Op Fl o Ar outfile
@@ -133,6 +136,8 @@ in question to be unconfigured rather th
 again.
 .It Fl s
 Read the key (nb: not the passphrase) from stdin.
+.It Fl t
+Timeout on reading the passphrase in seconds (default: 0 meaning no timeo=
ut).
 .It Fl U
 Unconfigure all the devices listed in the cgd configuration file.
 .It Fl u
Index: sbin/cgdconfig/cgdconfig.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sbin/cgdconfig/cgdconfig.c,v
retrieving revision 1.50
diff -u -p -r1.50 cgdconfig.c
=2D-- sbin/cgdconfig/cgdconfig.c	10 Apr 2019 06:11:37 -0000	1.50
+++ sbin/cgdconfig/cgdconfig.c	8 Apr 2020 23:36:46 -0000
@@ -83,6 +83,8 @@ enum action {
 	 ACTION_LIST			/* list configured devices */
 };

+int	timeout =3D 0;
+
 /* if nflag is set, do not configure/unconfigure the cgd's */

 int	nflag =3D 0;
@@ -203,7 +205,7 @@ main(int argc, char **argv)
 	p =3D params_new();
 	kg =3D NULL;

-	while ((ch =3D getopt(argc, argv, "CGUV:b:ef:gi:k:lno:spuv")) !=3D -1)
+	while ((ch =3D getopt(argc, argv, "CGUV:b:ef:gi:k:lno:st:puv")) !=3D -1)
 		switch (ch) {
 		case 'C':
 			set_action(&action, ACTION_CONFIGALL);
@@ -270,7 +272,9 @@ main(int argc, char **argv)
 		case 's':
 			set_action(&action, ACTION_CONFIGSTDIN);
 			break;
-
+		case 't':
+			timeout =3D atoi(optarg);
+			break;
 		case 'u':
 			set_action(&action, ACTION_UNCONFIGURE);
 			break;
@@ -387,12 +391,13 @@ maybe_getpass(char *prompt)

 	switch (pflag) {
 	case PFLAG_GETPASS:
-		p =3D getpass_r(prompt, buf, sizeof(buf));
+		p =3D getpassfd(prompt, buf, sizeof(buf), NULL,
+		    GETPASS_NEED_TTY, timeout);
 		break;

 	case PFLAG_GETPASS_ECHO:
 		p =3D getpassfd(prompt, buf, sizeof(buf), NULL,
-		    GETPASS_ECHO|GETPASS_ECHO_NL|GETPASS_NEED_TTY, 0);
+		    GETPASS_ECHO|GETPASS_ECHO_NL|GETPASS_NEED_TTY, timeout);
 		break;

 	case PFLAG_STDIN:
Index: sbin/fsck/fsck.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sbin/fsck/fsck.c,v
retrieving revision 1.52
diff -u -p -r1.52 fsck.c
=2D-- sbin/fsck/fsck.c	25 Oct 2014 22:00:19 -0000	1.52
+++ sbin/fsck/fsck.c	8 Apr 2020 23:36:46 -0000
@@ -246,6 +246,7 @@ main(int argc, char *argv[])
 static void *
 isok(struct fstab *fs)
 {
+	int fsreadfd;

 	if (fs->fs_passno =3D=3D 0)
 		return NULL;
@@ -253,6 +254,17 @@ isok(struct fstab *fs)
 	if (BADTYPE(fs->fs_type))
 		return NULL;

+	if (strstr(fs->fs_mntops, "opt")) {
+		if ((fsreadfd =3D open(fs->fs_spec, O_RDONLY)) < 0) {
+			if (errno =3D=3D ENXIO) {
+				printf("skipping unconfigured optional device %s\n",
+				       fs->fs_spec);
+				return NULL;
+			}
+		} else
+			close(fsreadfd);
+	}
+
 	if (!selected(fs->fs_vfstype))
 		return NULL;

>Audit-Trail:
From: Alexander Nasonov <alnsn@yandex.ru>
To: gnats-bugs@netbsd.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, schaecsn@gmx.net
Subject: Re: bin/55157: Request: cgd: timeout on waiting for passphrase
Date: Sat, 25 Apr 2020 23:58:54 +0100

 schaecsn@gmx.net wrote:
 > I introduce a timeout flag for cgdconfig. A timeout can be configured in /=
 > etc/rc.conf via
 > cgd_flags=3D"-t 60"

 Would timeout(1) work for you?

 PS I have a bit similar problem on -current (but not on -9):
    /etc/rc/network always get stuck in ifconfig. If I abort it
    manually, login and restart, it works with 80-90% probability.

 -- 
 Alex

From: Stefan Schaeckeler <schaecsn@gmx.net>
To: gnats-bugs@netbsd.org, alnsn@yandex.ru
Cc: gnats-admin@netbsd.org,netbsd-bugs@netbsd.org
Subject: Re: bin/55157: Request: cgd: timeout on waiting for passphrase
Date: Sun, 26 Apr 2020 18:32:04 -0700 (PDT)

 >  > I introduce a timeout flag for cgdconfig. A timeout can be configured=
  in
 >  > /etc/rc.conf via
 >  > cgd_flags=3D3D"-t 60"
 >
 >  Would timeout(1) work for you?

 A user might enter the passphrase quite late and the timeout may happen wh=
 ile
 cdgconfig decrypts the device. Cdgconfig should not be killed in that stag=
 e.

 Also, the follow-up problems are not solved. The two services /etc/rc.d/fs=
 ck
 and /etc/rc.d/mountall will fail accessing /dev/cgd*.

  Stefan

From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/55157: Request: cgd: timeout on waiting for passphrase
Date: Mon, 27 Apr 2020 07:02:34 -0000 (UTC)

 schaecsn@gmx.net (Stefan Schaeckeler) writes:

 >Also, the follow-up problems are not solved. The two services /etc/rc.d/fsck
 >and /etc/rc.d/mountall will fail accessing /dev/cgd*.

 If you want "hot-plug" behaviour, you must not fsck or mount automatically
 during boot. Instead you do that whenever you access the disk first, e.g.
 by configuring the automounter.

 -- 
 -- 
                                 Michael van Elst
 Internet: mlelstv@serpens.de
                                 "A potential Snark may lurk in every tree."

From: Alexander Nasonov <alnsn@yandex.ru>
To: gnats-bugs@netbsd.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, schaecsn@gmx.net
Subject: Re: bin/55157: Request: cgd: timeout on waiting for passphrase
Date: Tue, 28 Apr 2020 00:00:42 +0100

 Stefan Schaeckeler wrote:
 >  A user might enter the passphrase quite late and the timeout may happen while
 >  cdgconfig decrypts the device. Cdgconfig should not be killed in that stage.

 A user might run out of time while trying to correct a typo. You
 can't rely on timeouts (especially if you don't see a countdown
 and you have no idea how much time you have).

 >  Also, the follow-up problems are not solved. The two services
 >  /etc/rc.d/fsck and /etc/rc.d/mountall will fail accessing /dev/cgd*.

 I don't think our rc(8) is designed to handle fallbacks. If something
 goes wrong, we drop to a single-user shell.

 -- 
 Alex

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.