*BSD News Article 85072


Return to BSD News archive

Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.carno.net.au!harbinger.cc.monash.edu.au!news.mel.connect.com.au!munnari.OZ.AU!spool.mu.edu!newspump.sol.net!www.nntp.primenet.com!nntp.primenet.com!news.texas.net!node2.frontiernet.net!news.interactive.net!news.new-york.net!wlbr!moe.2bsd.com!sms
From: sms@moe.2bsd.com (Steven M. Schultz)
Subject: panic in sysctl(2) (#353)
Organization: 2BSD, Simi Valley CA USA
Message-ID: <E2JK31.G5v@moe.2bsd.com>
Date: Tue, 17 Dec 1996 04:49:49 GMT
Lines: 116
Xref: euryale.cc.adfa.oz.au comp.bugs.2bsd:715

Subject: panic in sysctl(2) (#353)
Index:	sys/kern_sysctl.c 2.11BSD

Description:
	Using sysctl(2) to retrieve the process table can panic when
	a process in the state SZOMB (a zombie process) is encountered.

Repeat-By:
	Have a zombie process present in the system and then run a program
	which does something similar to:

		int mib[3], i, size;

		mib[0] = CTL_KERN;
		mib[1] = KERN_PROC;
		mib[2] = KERN_PROC_ALL;
		i = sysctl(mib, 3, NULL, &size, NULL, 0);

Fix:
	Under 2.11BSD several pieces of information about a process are
	NOT kept in the "proc table".  Some information about a process
	is kept in the 'u area' (which can be swapped out with the process).

	In 4.4BSD, from where sysctl() was ported, there is effectively no
	'u area' because all process information was moved into the proc
	table (mushrooming the proc table entry size but what's a couple
	hundred kb of kernel address space these days?) and thus even 'zombie'
	processes have a 'real uid' and so on.

	When the process table is retrieved via sysctl() the 'real uid', 
	'controlling terminal', and 'controlling terminal device number' are 
	obtained from the 'u area' (by reading the swap area if the process
	is swapped out at the time) of a process rather than the 'proc table'.

	The problem was that I forgot zombies do not have a 'u area' 
	associated with them.  Referring to the 'u area' of a zombie will
	give indeterminate results ranging from incorrect/bogus data to
	a kernel panic.

	This problem was spotted when testing the 'identd' server.  Sysctl()
	is used by the 'libident' (the client side library of 'identd') to 
	retrieve process table information and one of the test programs elicited
	a kernel panic rather than the user id associated with a network 
	connection.  Oops ;)

	When a 'zombie' process is encounted now the "nobody" (-2) uid is
	returned and the controlling terminal is set to 'NODEV' (-1).

	Cut where indicated, saving to a file (/tmp/353) and then:

		patch -p0 < /tmp/353
		cd /sys/YOUR_KERNEL
		make
		make install
		reboot

	You should, if you keep a spare GENERIC kernel around, rebuild the
	generic kernel too:

		cd /sys/GENERIC
		make
		mv unix /genunix

	As always these, and all previous updates to 2.11BSD, are available
	via anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in
	the directory /pub/2.11BSD.

========================cut here=======================
*** /sys/sys/kern_sysctl.c.old	Sun Oct 29 00:08:01 1995
--- /sys/sys/kern_sysctl.c	Fri Dec 13 22:44:26 1996
***************
*** 33,39 ****
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)kern_sysctl.c	8.4.3 (2.11BSD GTE) 1995/10/29
   */
  
  /*
--- 33,39 ----
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)kern_sysctl.c	8.4.4 (2.11BSD GTE) 1996/12/13
   */
  
  /*
***************
*** 994,999 ****
--- 994,1006 ----
  	struct	tty	*ttyp;
  	struct	user	*up;
  
+ 	if	(p->p_stat == SZOMB)
+ 		{
+ 		*rup = (uid_t)-2;
+ 		*ttp = NULL;
+ 		*tdp = NODEV;
+ 		return;
+ 		}
  	if	(p->p_flag & SLOAD)
  		{
  		mapseg5(p->p_addr, (((USIZE - 1) << 8) | RO));
*** /VERSION.old	Mon Dec  9 21:59:50 1996
--- /VERSION	Mon Dec 16 19:57:22 1996
***************
*** 1,4 ****
! Current Patch Level: 352
  
  2.11 BSD
  ============
--- 1,4 ----
! Current Patch Level: 353
  
  2.11 BSD
  ============