From 8402d33aa38aed7c7ba1e0bbd46636e37ae2716c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 7 Oct 2016 13:41:28 +0000 Subject: [PATCH] When making a pause after detecting hard kill of the single-user shell, ensure that we do sleep for at least the specified time, in presence of signals. Interrupted sleep(3) is followed by _exit(), which might cause 'Going nowhere without my init' panic if init(8) exits before the reboot(2) really started, or before SIGTSTP stopped init(8) (both events are initiated by the parallel reboot(8) operation). I do not see other calls to sleep(STALL_TIMEOUT) as having the same disasterous consequences and kept them as is until the similar change is proven required. Reported and tested by: Andy Farkas Sponsored by: The FreeBSD Foundation MFC after: 3 weeks --- sbin/init/init.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sbin/init/init.c b/sbin/init/init.c index bda86b54e01..24785fe827a 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -870,6 +870,7 @@ single_user(void) sigset_t mask; const char *shell; char *argv[2]; + struct timeval tv, tn; #ifdef SECURE struct ttyent *typ; struct passwd *pp; @@ -1002,7 +1003,14 @@ single_user(void) * reboot(8) killed shell? */ warning("single user shell terminated."); - sleep(STALL_TIMEOUT); + gettimeofday(&tv, NULL); + tn = tv; + tv.tv_sec += STALL_TIMEOUT; + while (tv.tv_sec > tn.tv_sec || (tv.tv_sec == + tn.tv_sec && tv.tv_usec > tn.tv_usec)) { + sleep(1); + gettimeofday(&tn, NULL); + } _exit(0); } else { warning("single user shell terminated, restarting");