NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/55157: Request: cgd: timeout on waiting for passphrase



>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
>Originator:     schaecsn%gmx.net@localhost
>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@localhost:/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;



Home | Main Index | Thread Index | Old Index