Subject: sysctl(KERN_PROC) causes panic if processes are swapped out (#229) Index: sys/kern_sysctl.c 2.11BSD Description: If the sysctl(3) routine is used to retrieve information about processes and there are any swapped out processes in the system the kernel segmentation faults. Repeat-By: Make the system busy enough to initiate swapping. Then run the 'w' command. Note the resulting panic. This is because 'w' uses sysctl(3) with a function of KERN_PROC to retrieve information about which processes are running on the terminals. Fix: Apply the fix below, recompile the kernel, install and reboot. The bug was introduced by a case of brain fade on my part. The problem never showed up until a site in Norway ran 3 Ingres sessions at once on a 2mb system. (Sorry about that Tom, if it's any consolation I crashed the 3mb 11/44 at work a couple nights ago ;-)). The swap area is allocated in units of 512 byte sectors not 1024 byte filesystem blocks. The routine which reads the swap area (to access the u area of swapped processes) was reading garbage instead of process u areas. 'bread' is only to be used when reading filesystem aligned 1kb blocks. swap space can be (and frequently is) aligned on sector (512byte) boundaries. To apply the update: 1) Save the following to a file (/tmp/229) 2) patch -p0 < /tmp/229 3) cd /sys/YOUR_KERNEL_NAME 4) make 5) mv /unix /ounix mv /netnix /onetnix mv unix netnix / chmod 744 /unix /netnix fastboot 6) After the system comes back up you can remove /ounix /onetix. ==================cut here================ *** /sys/sys/kern_sysctl.c.old Thu Jan 19 23:20:51 1995 --- /sys/sys/kern_sysctl.c Mon Mar 6 20:56:41 1995 *************** *** 33,39 **** * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * @(#)kern_sysctl.c 8.4.1 (2.11BSD GTE) 1/15/95 */ /* --- 33,39 ---- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * @(#)kern_sysctl.c 8.4.2 (2.11BSD GTE) 3/06/95 */ /* *************** *** 55,60 **** --- 55,61 ---- #include #include #include + #include sysctlfn kern_sysctl; sysctlfn hw_sysctl; *************** *** 979,985 **** struct tty **ttp; dev_t *tdp; { ! struct buf *bp; dev_t ttyd; uid_t ruid; struct tty *ttyp; --- 980,986 ---- struct tty **ttp; dev_t *tdp; { ! register struct buf *bp; dev_t ttyd; uid_t ruid; struct tty *ttyp; *************** *** 995,1002 **** } else { ! bp = bread(swapdev, (long)p->p_addr); ! if (!bp) { ttyd = NODEV; ttyp = NULL; --- 996,1011 ---- } else { ! bp = geteblk(); ! bp->b_dev = swapdev; ! bp->b_blkno = (daddr_t)p->p_addr; ! bp->b_bcount = DEV_BSIZE; /* XXX */ ! bp->b_flags = B_READ; ! ! (*bdevsw[major(swapdev)].d_strategy)(bp); ! biowait(bp); ! ! if (u.u_error) { ttyd = NODEV; ttyp = NULL; *************** *** 1009,1020 **** ttyd = up->u_ttyd; /* u_ttyd = offset 654 */ ttyp = up->u_ttyp; /* u_ttyp = offset 652 */ mapout(bp); - bp->b_flags |= B_AGE; - brelse(bp); } } *rup = ruid; *ttp = ttyp; *tdp = ttyd; - return; } --- 1018,1029 ---- ttyd = up->u_ttyd; /* u_ttyd = offset 654 */ ttyp = up->u_ttyp; /* u_ttyp = offset 652 */ mapout(bp); } + bp->b_flags |= B_AGE; + brelse(bp); + u.u_error = 0; /* XXX */ } *rup = ruid; *ttp = ttyp; *tdp = ttyd; } *** /VERSION.old Mon Feb 6 20:42:03 1995 --- /VERSION Thu Mar 9 19:26:13 1995 *************** *** 1,4 **** ! Current Patch Level: 228 2.11 BSD ============ --- 1,4 ---- ! Current Patch Level: 229 2.11 BSD ============