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 <sys/map.h>
  #include <sys/sysctl.h>
  #include <machine/cpu.h>
+ #include <conf.h>
  
  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
  ============
