From nobody@FreeBSD.org  Wed Mar 24 12:06:30 2004
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 7FDD316A4CF
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 24 Mar 2004 12:06:30 -0800 (PST)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 778BC43D1D
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 24 Mar 2004 12:06:30 -0800 (PST)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.10/8.12.10) with ESMTP id i2OK6U72090459
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 24 Mar 2004 12:06:30 -0800 (PST)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.10/8.12.10/Submit) id i2OK6Uqu090458;
	Wed, 24 Mar 2004 12:06:30 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200403242006.i2OK6Uqu090458@www.freebsd.org>
Date: Wed, 24 Mar 2004 12:06:30 -0800 (PST)
From: Mike Hibler <mike@cs.utah.edu>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Reboot command needs to protect itself from signals
X-Send-Pr-Version: www-2.3

>Number:         64664
>Category:       bin
>Synopsis:       Reboot command needs to protect itself from signals
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar 24 12:10:19 PST 2004
>Closed-Date:    Wed Aug 02 13:06:24 GMT 2006
>Last-Modified:  Wed Aug 02 13:06:24 GMT 2006
>Originator:     Mike Hibler
>Release:        4.7-RELEASE
>Organization:
University of Utah
>Environment:
FreeBSD e.rroutetest.testbed.emulab.net 4.7-RELEASE FreeBSD 4.7-RELEASE #0: Thu Feb  5 19:56:28 MST 2004     root@node.fastbuild.testbed.emulab.net:/usr/src/sys/compile/TESTBED-LINKDELAY  i386
>Description:
      Invoking system("/sbin/reboot") from within a perl script causes the reboot command to be killed along with all the other processes, after it has STOPed init but before it has done the reboot syscall.  The result is that the system is terminally wedged.

The issue is that /sbin/reboot is not protecting itself adequately from signals.  It ignores SIGHUP, assuming that that is the worse thing its dying parent (or someone else) is going to try to do to it.  But it appears that perl, or at least this script, propogates the SIGTERM signal it receives on to reboot.

>How-To-Repeat:
      Doesn't happen all the time, its a timing thing.
>Fix:
      In the window between when reboot SIGTSTPs init and when it does the reboot syscall, reboot had better not die.  Thus it should block all possible signals during that window.

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed 
State-Changed-By: bms 
State-Changed-When: Wed Jun 16 00:01:25 GMT 2004 
State-Changed-Why:  
I haven't reproduced the issue, but have provided a patch for the 
submitter to test with; casual code inspection suggests the 
issue may be there (in both branches). 


Responsible-Changed-From-To: freebsd-bugs->bms 
Responsible-Changed-By: bms 
Responsible-Changed-When: Wed Jun 16 00:01:25 GMT 2004 
Responsible-Changed-Why:  
I'll take this 

http://www.freebsd.org/cgi/query-pr.cgi?pr=64664 

From: Bruce M Simpson <bms@spc.org>
To: Mike Hibler <mike@cs.utah.edu>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: bin/64664: Reboot command needs to protect itself from signals
Date: Wed, 16 Jun 2004 01:00:16 +0100

 --m972NQjnE83KvVa/
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Try the enclosed patch (against HEAD, but applies cleanly to RELENG_4).
 
 Regards,
 BMS
 
 --m972NQjnE83KvVa/
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="reboot-sigs.patch"
 
 Index: reboot.c
 ===================================================================
 RCS file: /home/ncvs/src/sbin/reboot/reboot.c,v
 retrieving revision 1.20
 diff -u -r1.20 reboot.c
 --- reboot.c	9 Apr 2004 19:58:35 -0000	1.20
 +++ reboot.c	15 Jun 2004 23:58:21 -0000
 @@ -69,6 +69,7 @@
  	u_int pageins;
  	char *kernel, *p;
  	const char *user;
 +	sigset_t sigs, osigs;
  
  	if (strstr((p = rindex(*argv, '/')) ? p + 1 : *argv, "halt")) {
  		dohalt = 1;
 @@ -114,7 +115,10 @@
  	}
  
  	if (qflag) {
 +		sigfillset(&sigs);
 +		sigprocmask(SIG_BLOCK, &sigs, &osigs);
  		reboot(howto);
 +		sigprocmask(SIG_SETMASK, &osigs, NULL);
  		err(1, NULL);
  	}
  
 @@ -194,7 +198,10 @@
  		(void)sleep(2 * i);
  	}
  
 +	sigfillset(&sigs);
 +	sigprocmask(SIG_BLOCK, &sigs, &osigs);
  	reboot(howto);
 +	sigprocmask(SIG_SETMASK, &osigs, NULL);
  	/* FALLTHROUGH */
  
  restart:
 
 --m972NQjnE83KvVa/--

From: Bruce M Simpson <bms@spc.org>
To: Mike Hibler <mike@cs.utah.edu>
Cc: phk@FreeBSD.org, freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/64664: Reboot command needs to protect itself from signals
Date: Wed, 16 Jun 2004 08:20:55 +0100

 --yH1ZJFh+qWm+VodA
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Here's a revised patch for the possible race condition in this PR,
 urged after review from phk@.
 
 Regards,
 BMS
 
 --yH1ZJFh+qWm+VodA
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="reboot-race.patch"
 
 Index: reboot.c
 ===================================================================
 RCS file: /home/ncvs/src/sbin/reboot/reboot.c,v
 retrieving revision 1.19
 diff -u -r1.19 reboot.c
 --- reboot.c	3 May 2003 18:41:59 -0000	1.19
 +++ reboot.c	16 Jun 2004 07:16:29 -0000
 @@ -156,12 +156,16 @@
  	if (!nflag)
  		sync();
  
 +	/*
 +	 * Ignore the SIGHUP we get when our parent shell dies;
 +	 * we might race with init delivering this signal to us
 +	 * before we can actually issue reboot(), so ignore it now.
 +	 */
 +	(void)signal(SIGHUP, SIG_IGN);
 +
  	/* Just stop init -- if we fail, we'll restart it. */
  	if (kill(1, SIGTSTP) == -1)
  		err(1, "SIGTSTP init");
 -
 -	/* Ignore the SIGHUP we get when our parent shell dies. */
 -	(void)signal(SIGHUP, SIG_IGN);
  
  	/* Send a SIGTERM first, a chance to save the buffers. */
  	if (kill(-1, SIGTERM) == -1 && errno != ESRCH)
 
 --yH1ZJFh+qWm+VodA--
State-Changed-From-To: analyzed->suspended 
State-Changed-By: bms 
State-Changed-When: Mon Apr 25 21:58:55 GMT 2005 
State-Changed-Why:  
Timeout on submitter feedback. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=64664 
Responsible-Changed-From-To: bms->freebsd-bugs 
Responsible-Changed-By: bms 
Responsible-Changed-When: Wed Aug 2 12:35:30 UTC 2006 
Responsible-Changed-Why:  
I disown thee -- no feedback. The patch is OK, but probably doesn't 
fix the condition the submitter describes, even if it still exists. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=64664 
State-Changed-From-To: suspended->patched 
State-Changed-By: bms 
State-Changed-When: Wed Aug 2 12:42:26 UTC 2006 
State-Changed-Why:  
I just committed this on HEAD. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=64664 
State-Changed-From-To: patched->closed 
State-Changed-By: bms 
State-Changed-When: Wed Aug 2 13:06:06 UTC 2006 
State-Changed-Why:  
A more appropriate solution obtained from NetBSD. 
MFC timer set. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=64664 
>Unformatted:
