Subject: bin/1374: If single-user login fails, fscks aren't done
To: None <gnats-bugs@gnats.netbsd.org>
From: None <Mark_Weaver@brown.edu>
List: netbsd-bugs
Date: 08/18/1995 06:15:35
>Number: 1374
>Category: bin
>Synopsis: If single-user login fails, fscks aren't done
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: mhw
>Arrival-Date: Fri Aug 18 06:20:01 1995
>Last-Modified:
>Originator: Mark Weaver
>Organization:
Brown University Department of Computer Science
>Release: NetBSD-current 8/11/95
>Environment:
NetBSD cis-ts4-slip4.cis.brown.edu 1.0A NetBSD 1.0A (WEAVER) #0: Fri Aug 11 19:26:06 EDT 1995 mhw@cis-ts4-slip9.cis.brown.edu:/usr/src/sys/arch/i386/compile/WEAVER i386
>Description:
Currently, if the console entry in /etc/ttys is not "secure" and
single-user login fails, the fscks are not done. Obviously this is
sub-optimal behavior.
>How-To-Repeat:
Make console insecure in /etc/ttys.
Start to enter single-user mode on boot, but just hit return at the
password prompt.
It will skip the fscks.
>Fix:
diff -c src/sbin/init/init.c.mhw1 src/sbin/init/init.c
*** src/sbin/init/init.c.mhw1 Tue May 30 08:35:25 1995
--- src/sbin/init/init.c Fri Aug 18 06:00:41 1995
***************
*** 94,99 ****
--- 94,110 ----
#define STALL_TIMEOUT 30 /* wait N secs after warning */
#define DEATH_WATCH 10 /* wait N secs for procs to die */
+ /*
+ * Exit status returned from signal-user shell to indicate that
+ * single-user login was not successful.
+ *
+ * XXX If the shell happens to return NOLOGIN_STATUS (eg, if the
+ * last command run also did), init will think it should run fsck,
+ * which could be bad if any volumes were mounted read-write during
+ * single-user.
+ */
+ #define NOLOGIN_STATUS 127
+
void handle __P((sig_t, ...));
void delset __P((sigset_t *, ...));
***************
*** 593,600 ****
write(2, banner, sizeof banner - 1);
for (;;) {
clear = getpass("Password:");
! if (clear == 0 || *clear == '\0')
! _exit(0);
password = crypt(clear, pp->pw_passwd);
memset(clear, 0, _PASSWORD_LEN);
if (strcmp(password, pp->pw_passwd) == 0)
--- 604,617 ----
write(2, banner, sizeof banner - 1);
for (;;) {
clear = getpass("Password:");
! if (clear == 0 || *clear == '\0') {
! /*
! * Since single-user login was not successful,
! * we tell init to run fsck by returning a
! * special exit status.
! */
! _exit(NOLOGIN_STATUS);
! }
password = crypt(clear, pp->pw_passwd);
memset(clear, 0, _PASSWORD_LEN);
if (strcmp(password, pp->pw_passwd) == 0)
***************
*** 690,697 ****
return (state_func_t) single_user;
}
}
- runcom_mode = FASTBOOT;
#ifndef LETS_GET_SMALL
return (state_func_t) runcom;
#else /* LETS_GET_SMALL */
--- 707,715 ----
return (state_func_t) single_user;
}
}
+ else if (WEXITSTATUS(status) != NOLOGIN_STATUS)
+ runcom_mode = FASTBOOT;
#ifndef LETS_GET_SMALL
return (state_func_t) runcom;
#else /* LETS_GET_SMALL */
>Audit-Trail:
>Unformatted: