*BSD News Article 88726


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.rmit.EDU.AU!goanna.cs.rmit.edu.au!news.apana.org.au!cantor.edge.net.au!news.teragen.com.au!news.access.net.au!news.mel.connect.com.au!news.mel.aone.net.au!grumpy.fl.net.au!news.webspan.net!ix.netcom.com!super.zippo.com!zdc!su-news-hub1.bbnplanet.com!news.bbnplanet.com!newsxfer3.itd.umich.edu!cloudbreak.rs.itd.umich.edu!news.ececs.uc.edu!news.kei.com!news.thenet.net!wlbr!moe.2bsd.com!sms
From: sms@moe.2bsd.com (Steven M. Schultz)
Subject: toyset and May31, bug in #363, /usr/share/zoneinfo modes wrong (#364)
Organization: 2BSD, Simi Valley CA USA
Message-ID: <E59D4H.EKD@moe.2bsd.com>
Date: Sat, 8 Feb 1997 00:24:17 GMT
Lines: 388
Xref: euryale.cc.adfa.oz.au comp.bugs.2bsd:736

Subject: toyset and May31, bug in #363, /usr/share/zoneinfo modes wrong (#364)
Index:	sys/vfs_vnops.c,ufs_inode.c 2.11BSD

Description:
	In addition to implementing the fd(4) driver the changes made 
	in update #363 introduced a bug that could hang the system by
	attempting to lock an inode that was already locked.

	The timezone files in /usr/share/zoneinfo should be publically readable
	so that any process in the system can perform TZ manipulations.
	
	The standalone program 'toyset' (used to set the TOY clock on 11/93
	and 11/94 systems) could not handle the day "May 31".

Repeat-By:
	su nobody
	find / -print > /dev/null

	As soon as 'find' encounters a directory which can not be opened for
	reading the 'find' process will hang.  Eventually the entire system
	will hang as more and more processes attempt to lock already locked
	inodes.

	Alternatively 'rlogin' into the system repeatedly.  Since the ptys
	are being left locked eventually rlogin will encounter the "no more
	ptys" error.

	ls -l /usr/share/zoneinfo

	Note that the mode of the files may not be 644 or 444.

	Use 'toyset' on an 11/93 and attempt to set the date to May 31.

Fix:

	A bug was introducted in #363 ;-(

	Everything was working fine (system was able to recompile the kernel,
	etc) but /usr/adm/weekly pointed out a problem with inode locking -
	the 'find' which is done (to rebuild the /var/db/find.codes database)
	pointed out the problem.

	In the process of fixing the bug I stumbled across a typo made
	when 4.3BSD was originally ported to the pdp-11 (no, I didn't make
	the typo - was Keith Bostic in this case).  There is a '#ifndef'
	in ufs_inode.c that should have been '#ifdef'.  This error dates
	back to about 1987 or 1988!

	The symptom of the bug is that the 'find' command hangs when it
	encounters a directory it can not read.  'namei()' returns a locked
	inode.  The new function 'vn_open()' does a 'ilock' prior to 
	reporting the access error - but if the inode is locked there is
	a deadlock situation.  The "fix" was to remove the superfluous 'ilock'
	call (added because it looked like the "right thing to do") but that 
	ran into the typographical error in ufs_inode.c.

	The intent of the '#ifndef' in ufs_inode.c was to ignore the locked
	status of the inode because as the comments indicate there are
	a number of places that do not gratuitously lock the inode prior to 
	calling 'iput()'.

	A path thru the "open" code was accidentally created which caused an 
	unlocked inode to be passed out of vn_open() to iput().  When openi()
	returns an error the inode must be locked before calling iput() because
	iunlock() was called immediately prior to openi().

	Over the course of what turned out to be a very long night/morning
	a couple other buglets were spotted in the system:

	  The modes on the timezone files (/usr/share/zoneinfo) were wrong 
	  because the umask was not set properly before running 'zic' (the 
	  timezone info compiler).

	  The conf/Make.sunix file was out of sync with GENERIC/Make.sys
	  (my fault - I diff'd against the wrong version when creating the
	  patch).  

	  Alan Sieving (of Quickware Engineering Design) pointed out (very
	  nicely!) that I'd made an error a couple years ago in the 'toyset'
	  program used to program the TOY clock on the 11/93.  I'd overlooked
	  that May has 31 days rather than 30.

	To install the fixes cut where indicated saving to a file (/tmp/364)
	and then:

		patch -p0 < /tmp/364

		chmod -R a+r /usr/share/zoneinfo

		cd /sys/GENERIC
		make
		install -m 744 unix /genunix

		cd /sys/YOUR_KERNEL
		make
		make install
		reboot

	As always this and 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----------------------
*** /usr/src/sys/conf/Make.sunix.old	Fri Jan 31 08:33:06 1997
--- /usr/src/sys/conf/Make.sunix	Thu Feb  6 22:38:19 1997
***************
*** 10,16 ****
  # software without specific prior written permission. This software
  # is provided ``as is'' without express or implied warranty.
  #
! #	2.9 (2.11BSD GTE) 1997/1/31
  #
  #########################################################
  # Non-network, but separate I/D kernel			#
--- 10,16 ----
  # software without specific prior written permission. This software
  # is provided ``as is'' without express or implied warranty.
  #
! #	2.10 (2.11BSD GTE) 1997/2/6
  #
  #########################################################
  # Non-network, but separate I/D kernel			#
***************
*** 49,55 ****
  BASE=	br.o dh.o dhu.o dhv.o dkbad.o dr.o dz.o init_sysent.o kern_clock.o \
  	kern_descrip.o kern_mman.o kern_proc.o kern_sig.o kern_subr.o \
  	kern_synch.o lp.o machdep.o ra.o ram.o si.o \
! 	subr_rmap.o subr_xxx.o sys_inode.o sys_pipe.o trap.o tty.o \
  	tty_conf.o tty_subr.o tty_tb.o tty_tty.o ufs_alloc.o ufs_bio.o \
  	ufs_bmap.o ufs_dsort.o ufs_fio.o ufs_inode.o ufs_namei.o \
  	xp.o
--- 49,55 ----
  BASE=	br.o dh.o dhu.o dhv.o dkbad.o dr.o dz.o init_sysent.o kern_clock.o \
  	kern_descrip.o kern_mman.o kern_proc.o kern_sig.o kern_subr.o \
  	kern_synch.o lp.o machdep.o ra.o ram.o si.o \
! 	subr_rmap.o subr_xxx.o sys_inode.o trap.o tty.o \
  	tty_conf.o tty_subr.o tty_tb.o tty_tty.o ufs_alloc.o ufs_bio.o \
  	ufs_bmap.o ufs_dsort.o ufs_fio.o ufs_inode.o ufs_namei.o \
  	xp.o
***************
*** 64,70 ****
  OV6=	tmscp.o tmscpdump.o
  OV7=	rl.o mch_fpsim.o ingreslock.o ufs_disksubr.o
  OV8=	rx.o kern_sysctl.o vm_sched.o vm_text.o
! OV9=	kern_pdp.o kern_xxx.o ufs_syscalls2.o mem.o ufs_subr.o rk.o
  
  KERNOBJ=${CONF} ${BASE} ${OV1} ${OV2} ${OV3} ${OV4} ${OV5} \
  	${OV6} ${OV7} ${OV8} ${OV9} ${OV10} ${OV11} ${OV12} \
--- 64,70 ----
  OV6=	tmscp.o tmscpdump.o
  OV7=	rl.o mch_fpsim.o ingreslock.o ufs_disksubr.o
  OV8=	rx.o kern_sysctl.o vm_sched.o vm_text.o
! OV9=	kern_pdp.o kern_xxx.o ufs_syscalls2.o mem.o ufs_subr.o rk.o sys_pipe.o
  
  KERNOBJ=${CONF} ${BASE} ${OV1} ${OV2} ${OV3} ${OV4} ${OV5} \
  	${OV6} ${OV7} ${OV8} ${OV9} ${OV10} ${OV11} ${OV12} \
*** /usr/src/sys/sys/vfs_vnops.c.old	Tue Feb  4 19:53:19 1997
--- /usr/src/sys/sys/vfs_vnops.c	Fri Feb  7 12:28:04 1997
***************
*** 35,41 ****
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)vfs_vnops.c	8.14.1 (2.11BSD) 1997/2/4
   */
  
  #include <sys/param.h>
--- 35,41 ----
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)vfs_vnops.c	8.14.2 (2.11BSD) 1997/2/7
   */
  
  #include <sys/param.h>
***************
*** 149,166 ****
  		{
  		if	((error = u.u_error) == 0)
  			error = EINTR;
! 		goto bad;
  		}
  	if	(error = openi(ip, fmode))
! 		goto bad;
  	return(0);
  bad:
! 	ilock(ip);		/* XXX - iput ignores locked status */
  	iput(ip);
  	return(error);
  retuerr:
  	return(u.u_error);	/* XXX - Bletch */
  	}
  /*
   * Inode close call.  Pipes and sockets do NOT enter here.  This routine is
   * used by the kernel to close files it opened for itself (see kern_acct.c
--- 149,178 ----
  		{
  		if	((error = u.u_error) == 0)
  			error = EINTR;
! 		goto lbad;
  		}
  	if	(error = openi(ip, fmode))
! 		goto lbad;
  	return(0);
+ /*
+  * Gratuitous lock but it does (correctly) implement the earlier behaviour of
+  * copen (it also avoids a panic in iput).
+ */
+ 
+ lbad:
+ 	ilock(ip);
+ 
  bad:
! /*
!  * Do NOT do an 'ilock' here - this tag is to be used only when the inode is
!  * locked (i.e. from namei).
! */
  	iput(ip);
  	return(error);
  retuerr:
  	return(u.u_error);	/* XXX - Bletch */
  	}
+ 
  /*
   * Inode close call.  Pipes and sockets do NOT enter here.  This routine is
   * used by the kernel to close files it opened for itself (see kern_acct.c
*** /usr/src/sys/sys/ufs_inode.c.old	Mon Sep 30 19:37:15 1996
--- /usr/src/sys/sys/ufs_inode.c	Fri Feb  7 01:02:47 1997
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ufs_inode.c	1.6 (2.11BSD GTE) 1996/9/30
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ufs_inode.c	1.7 (2.11BSD GTE) 1997/2/7
   */
  
  #include "param.h"
***************
*** 293,299 ****
  	register struct inode *ip;
  {
  
! #ifndef notnow
  	/*
  	 * This code requires a lot of workarounds, you have to change
  	 * lots of places to gratuitously lock just so we can unlock it.
--- 293,299 ----
  	register struct inode *ip;
  {
  
! #ifdef notnow
  	/*
  	 * This code requires a lot of workarounds, you have to change
  	 * lots of places to gratuitously lock just so we can unlock it.
*** /usr/src/sys/sys/ufs_syscalls.c.old	Sat Feb  1 12:13:59 1997
--- /usr/src/sys/sys/ufs_syscalls.c	Fri Feb  7 10:34:33 1997
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ufs_syscalls.c	1.9 (2.11BSD GTE) 1997/1/30
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ufs_syscalls.c	1.10 (2.11BSD GTE) 1997/2/7
   */
  
  #include "param.h"
***************
*** 182,198 ****
  		return;
  		}
  	ip = ndp->ni_ip;
- #ifdef	DIAGNOSTIC
- 	if	(!ip)
- 		{
- 		printf("copen(%o,%o,%s) !ni_ip u_error %d\n", mode, 
- 			arg, fname,u.u_error);
-    		}
- #endif
  	u.u_dupfd = 0;
  
- /* Don't need to do this here because 'vn_open' returns an unlocked inode */
- /*	iunlock(ip);	*/
  	fp->f_data = (caddr_t)ip;
  
  	if	(flags & (O_EXLOCK | O_SHLOCK))
--- 182,189 ----
*** /usr/src/sys/pdpstand/toyset.s.old	Sat Aug 21 20:56:32 1993
--- /usr/src/sys/pdpstand/toyset.s	Thu Feb  6 22:12:55 1997
***************
*** 1,5 ****
--- 1,9 ----
  TOYCSR	= 177526
  
+ / February 6, 1997 - sms@moe.2bsd.com
+ / Forgot that May has 31 days.  Thanks to Alan Sieving (ars@quickware.com) for
+ / spotting this.
+ /
  / August 21, 1993 - Steven M. Schultz (sms@wlv.iipo.gtegsc.com)
  / This is a standalone program which is used to set the TOY (Time Of Year)
  / clock on a PDP-11/93 or 11/94.  If this program is run on other than a
***************
*** 358,364 ****
  
  	.data
  Mtab:
! 	.byte	31.,29.,31.,30.,30.,30.
  	.byte	31.,31.,30.,31.,30.,31.
  m_magic:
  	.byte	1,4,4,0,2,5,0,3,6,1,4,6
--- 362,368 ----
  
  	.data
  Mtab:
! 	.byte	31.,29.,31.,30.,31.,30.
  	.byte	31.,31.,30.,31.,30.,31.
  m_magic:
  	.byte	1,4,4,0,2,5,0,3,6,1,4,6
*** /usr/src/sys/GENERIC/Makefile.old	Sat Feb  1 10:35:14 1997
--- /usr/src/sys/GENERIC/Makefile	Thu Feb  6 22:38:55 1997
***************
*** 10,16 ****
  # software without specific prior written permission. This software
  # is provided ``as is'' without express or implied warranty.
  #
! #	2.9 (2.11BSD GTE) 1997/1/31
  #
  #########################################################
  # Non-network, but separate I/D kernel			#
--- 10,16 ----
  # software without specific prior written permission. This software
  # is provided ``as is'' without express or implied warranty.
  #
! #	2.10 (2.11BSD GTE) 1997/2/6
  #
  #########################################################
  # Non-network, but separate I/D kernel			#
*** /usr/src/share/zoneinfo/Makefile.old	Sun Dec  1 16:39:14 1996
--- /usr/src/share/zoneinfo/Makefile	Thu Feb  6 22:04:10 1997
***************
*** 1,4 ****
! # @(#)Makefile	1.4 Makefile 1996/12/1
  
  DESTDIR=
  
--- 1,4 ----
! # @(#)Makefile	1.5 Makefile 1997/2/6
  
  DESTDIR=
  
***************
*** 42,47 ****
--- 42,48 ----
  all:		zdump zic ${ZICMAN} ${ZDUMAN}
  
  install:	zic $(DATA) $(MAN)
+ 		umask 22
  		./zic -d ${SHARDIR} $(DATA)
  		install -c -m 444 -o bin -g bin ${SHARDIR}/${LOCALTIME} ${DESTDIR}/etc/localtime
  		install -c -m 444 -o bin -g bin $(ZICMAN) ${MANDIR}/${ZICMAN}
*** /VERSION.old	Sat Feb  1 15:53:05 1997
--- /VERSION	Thu Feb  6 22:43:10 1997
***************
*** 1,4 ****
! Current Patch Level: 363
  
  2.11 BSD
  ============
--- 1,5 ----
! Current Patch Level: 364
! Date: February 6, 1997
  
  2.11 BSD
  ============