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: