correct error handling in reboot(8)

Tony Finch <[email protected]>
Newsgroups gmane.os.freebsd.devel.audit
Message-ID <[email protected]>
I just noticed when looking at reboot(8) following the killall rant in
the recent RISKS that there a number of cases after SIGSTOPping init
in which it may abort calling err() but fail to restart init. This
patch uses atexit() to ensure that init is restarted if things go wrong.
The same problem and fix apply to -STABLE.

Index: reboot.c
===================================================================
RCS file: /home/ncvs/src/sbin/reboot/reboot.c,v
retrieving revision 1.15
diff -u -r1.15 reboot.c
--- reboot.c	26 Apr 2002 22:32:15 -0000	1.15
+++ reboot.c	9 May 2002 17:03:58 -0000
@@ -60,8 +60,9 @@
 #include <string.h>
 #include <unistd.h>
 
-void usage(void);
 u_int get_pageins(void);
+void restart_init(void);
+void usage(void);
 
 int dohalt;
 
@@ -69,7 +70,7 @@
 main(int argc, char *argv[])
 {
 	struct passwd *pw;
-	int ch, howto, i, fd, kflag, lflag, nflag, qflag, pflag, sverrno;
+	int ch, howto, i, fd, kflag, lflag, nflag, qflag, pflag;
 	u_int pageins;
 	char *kernel, *p;
 	const char *user;
@@ -156,6 +157,8 @@
 		sync();
 
 	/* Just stop init -- if we fail, we'll restart it. */
+	if (atexit(restart_init) == -1)
+		err(1, "atexit");
 	if (kill(1, SIGTSTP) == -1)
 		err(1, "SIGTSTP init");
 
@@ -187,24 +190,28 @@
 		if (kill(-1, SIGKILL) == -1) {
 			if (errno == ESRCH)
 				break;
-			goto restart;
+			err(1, "killall");
 		}
 		if (i > 5) {
-			(void)fprintf(stderr,
-			    "WARNING: some process(es) wouldn't die\n");
+			warnx("WARNING: some process(es) wouldn't die");
 			break;
 		}
 		(void)sleep(2 * i);
 	}
 
+	/*
+	 * If the reboot() succeeds then we never get control back,
+	 * otherwise we exit via some error reporting and restart_init().
+	 */
 	reboot(howto);
-	/* FALLTHROUGH */
+	err(1, "reboot failed");
+}
 
-restart:
-	sverrno = errno;
-	errx(1, "%s%s", kill(1, SIGHUP) == -1 ? "(can't restart init): " : "",
-	    strerror(sverrno));
-	/* NOTREACHED */
+void
+restart_init()
+{
+	if (kill(1, SIGHUP) == -1)
+		warn("can't restart init");
 }
 
 void

Tony.
-- 
f.a.n.finch <[email protected]> http://dotat.at/
CROMARTY FORTH TYNE DOGGER: NORTHEASTERLY 3 OR 4, OCCASIONALLY 5. PATCHY RAIN
AT FIRST. MODERATE OR GOOD WITH FOG PATCHES.

To Unsubscribe: send mail to [email protected]
with "unsubscribe freebsd-audit" in the body of the message
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.