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 --- 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 *************** *** 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 ============