Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Mar 1998 11:36:50 -0800
From:      Cy Schubert - ITSD Open Systems Group <cschuber@uumail.gov.bc.ca>
To:        "Vladimir A. Petrov" <V.Petrov@vaz.ru>
Cc:        Cy Schubert - ITSD Open Systems Group <cschuber@uumail.gov.bc.ca>, freebsd-stable@FreeBSD.ORG
Subject:   Re: Surprise Reboots 
Message-ID:  <199803231937.LAA14250@passer.osg.gov.bc.ca>
In-Reply-To: Your message of "Mon, 23 Mar 1998 23:08:28 %2B0400." <Pine.BSF.3.96.980323225709.13827B-100000@asm.vaz.ru> 

next in thread | previous in thread | raw e-mail | index | archive | help
> Good Day!
> 
> On Sun, 22 Mar 1998, Cy Schubert - ITSD Open Systems Group wrote:
> 
> > 2.2.5-RELEASE had a couple of problems that exhibited themselves as VM 
> > problems that caused the system to panic occasionally.  You can either 
> > upgrade to 2.2.6-BETA or email me and I will send you a 42K patch that 
> > fixes these and various other problems that I had, including a hack to 
> > fix a NULLFS panic (PR kern/5355).
> 
> I have a problem like that. Currently I use FreeBSD 2.2.5-STABLE and
> all works fine until I don't try to do 'make world'. When I start
> making world my system surprisely reboots after some time. I don't
> have any ideas about it because I don't found any error messages
> in log files and all reboots has happened without my presence.
> By this cause I still can't upgrade to 2.2.6-BETA. I have CVSuped
> tree but I can't rebuild from it. So, if Your patch may help me
> in this situation then it will be so kind if You send me Your
> patch.

Since I've received a number of requests for the patches, here they 
are.  They are a collection of stuff from the -stable CVS tree, an 
email I received from John Dyson (I hope I've spelled John's name 
correctly) about vfs_bio.c, two patches of my own to fix a FDESC 
filesystem fix (I believe committed in -stable or -current quite some 
time ago) and a NULLFS hack, various security fixes, some patches from 
the 2.2.5 Errata, and some other odds and sodds to fix various other 
problems I've had.  All of the patches I am enclosing, except for two 
of them, have been committed to the either the -stable or -current 
branches.  The two that have not been committed to the -stable or 
-current branches are my NULLFS hack (much discussion continues on the 
best way to solve this) and John's vfs_bio.c that he emailed me back in 
December to fix kern/4844 and other related VM problems.

Prior to applying to some of the patches below the systems would panic 
at least every 36 hours.  Now they stay up until I reboot them (days or 
weeks).  I believe that the VM patches and the vfs_bio.c patches are 
the ones

These patches should ONLY be applied to 2.2.5-RELEASE and should not be 
installed on anything else unless reworked for those systems.  These 
patches have made my systems stable.

Please discard any patches in the following that have already been 
incorporated in -stable.

diff -ur src/gnu/usr.bin/gzip/gzip.c src/gnu/usr.bin/gzip/gzip.c
--- src/gnu/usr.bin/gzip/gzip.c	Mon May 29 22:00:33 1995
+++ src/gnu/usr.bin/gzip/gzip.c	Sun Dec 28 09:22:42 1997
@@ -1006,6 +1006,13 @@
     char *dot; /* pointer to ifname extension, or NULL */
 #endif
 
+    if (strlen(iname) >= sizeof(ifname) - 3) {
+       errno = ENAMETOOLONG;
+       perror(iname);
+       exit_code = ERROR;
+       return ERROR;
+    }
+
     strcpy(ifname, iname);
 
     /* If input file exists, return OK. */
diff -ur src/gnu/usr.bin/gzip/inflate.c src/gnu/usr.bin/gzip/inflate.c
--- src/gnu/usr.bin/gzip/inflate.c	Mon May 29 22:00:37 1995
+++ src/gnu/usr.bin/gzip/inflate.c	Sun Dec 28 09:22:43 1997
@@ -767,6 +767,8 @@
     return i;                   /* incomplete code set */
   }
 
+  if (tl == NULL) /* Grrrhhh */
+       return 2;
 
   /* read in literal and distance code lengths */
   n = nl + nd;
diff -ur src/lib/libc/gen/getpass.c src/lib/libc/gen/getpass.c
--- src/lib/libc/gen/getpass.c	Fri Jul 12 11:53:47 1996
+++ src/lib/libc/gen/getpass.c	Wed Feb 25 20:25:16 1998
@@ -44,38 +44,8 @@
 #include <unistd.h>
 
 static	struct termios oterm, term;
-static	sig_t ointhandler, oquithandler, otstphandler, oconthandler;
 static	FILE *fp;
 
-static void
-sighandler(int signo)
-{
-	/* restore tty state */
-	(void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &oterm);
-
-	/* restore old sig handlers */
-	(void)signal(SIGINT, ointhandler);
-	(void)signal(SIGQUIT, oquithandler);
-	(void)signal(SIGTSTP, otstphandler);
-
-	/* resend us this signal */
-	(void)kill(getpid(), signo);
-}
-
-/* ARGSUSED */
-static void
-sigconthandler(int signo)
-{
-	/* re-install our signal handlers */
-	ointhandler = signal(SIGINT, sighandler);
-	oquithandler = signal(SIGQUIT, sighandler);
-	otstphandler = signal(SIGTSTP, sighandler);
-
-	/* turn off echo again */
-	(void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &term);
-}
-
-
 char *
 getpass(prompt)
 	const char *prompt;
@@ -84,6 +54,7 @@
 	register char *p;
 	FILE *outfp;
 	static char buf[_PASSWORD_LEN + 1];
+	sigset_t oset, nset;
 
 	/*
 	 * read and write to /dev/tty if possible; else read from
@@ -94,11 +65,15 @@
 		fp = stdin;
 	}
 
-	ointhandler = signal(SIGINT, sighandler);
-	oquithandler = signal(SIGQUIT, sighandler);
-	otstphandler = signal(SIGTSTP, sighandler);
-	oconthandler = signal(SIGCONT, sigconthandler);
-
+	/*
+	 * note - blocking signals isn't necessarily the
+	 * right thing, but we leave it for now.
+	 */
+	sigemptyset(&nset);
+	sigaddset(&nset, SIGINT);
+	sigaddset(&nset, SIGTSTP);
+	(void)sigprocmask(SIG_BLOCK, &nset, &oset);
+	
 	(void)tcgetattr(fileno(fp), &oterm);
 	term = oterm;
 	term.c_lflag &= ~ECHO;
@@ -112,11 +87,7 @@
 	(void)write(fileno(outfp), "\n", 1);
 	(void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &oterm);
 
-	/* restore old sig handlers */
-	(void)signal(SIGINT, ointhandler);
-	(void)signal(SIGQUIT, oquithandler);
-	(void)signal(SIGTSTP, otstphandler);
-	(void)signal(SIGCONT, oconthandler);
+	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
 
 	if (fp != stdin)
 		(void)fclose(fp);
diff -ur src/sbin/ccdconfig/ccdconfig.c src/sbin/ccdconfig/ccdconfig.c
--- src/sbin/ccdconfig/ccdconfig.c	Tue Jun 10 23:58:39 1997
+++ src/sbin/ccdconfig/ccdconfig.c	Thu Jan  1 09:19:35 1998
@@ -1,4 +1,4 @@
-/* $Id: ccdconfig.c,v 1.4.4.1 1997/06/11 06:58:39 charnier Exp $ */
+/* $Id: ccdconfig.c,v 1.4.4.2 1997/12/30 05:15:13 imp Exp $ */
 
 /*	$NetBSD: ccdconfig.c,v 1.2.2.1 1995/11/11 02:43:35 thorpej Exp $	*/
 
@@ -161,6 +161,15 @@
 	if (options > 1)
 		usage();
 
+	/*
+	 * Discard setgid privileges if not the running kernel so that bad
+	 * guys can't print interesting stuff from kernel memory.
+	 */
+	if (core != NULL || kernel != NULL || action != CCD_DUMP) {
+		setegid(getgid());
+		setgid(getgid());
+	}
+
 	switch (action) {
 		case CCD_CONFIG:
 		case CCD_UNCONFIG:
@@ -307,11 +316,16 @@
 	char line[_POSIX2_LINE_MAX];
 	char *cp, **argv;
 	int argc, rval;
+	gid_t egid;
 
+	egid = getegid();
+	setegid(getgid());
 	if ((f = fopen(ccdconf, "r")) == NULL) {
+		setegid(egid);
 		warn("fopen: %s", ccdconf);
 		return (1);
 	}
+	setegid(egid);
 
 	while (fgets(line, sizeof(line), f) != NULL) {
 		argc = 0;
diff -ur src/sbin/restore/tape.c src/sbin/restore/tape.c
--- src/sbin/restore/tape.c	Sun Mar  2 06:43:51 1997
+++ src/sbin/restore/tape.c	Tue Mar  3 18:54:46 1998
@@ -231,7 +231,9 @@
 		fprintf(stderr, "cannot stat .: %s\n", strerror(errno));
 		done(1);
 	}
-	if (stbuf.st_blksize > 0 && stbuf.st_blksize <= MAXBSIZE)
+	if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE )
+		fssize = TP_BSIZE;
+	if (stbuf.st_blksize >= TP_BSIZE && stbuf.st_blksize <= MAXBSIZE)
 		fssize = stbuf.st_blksize;
 	if (((fssize - 1) & fssize) != 0) {
 		fprintf(stderr, "bad block size %d\n", fssize);
diff -ur src/sys/i386/i386/identcpu.c src/sys/i386/i386/identcpu.c
--- src/sys/i386/i386/identcpu.c	Fri Oct  3 07:29:48 1997
+++ src/sys/i386/i386/identcpu.c	Wed Dec 24 11:15:57 1997
@@ -91,6 +91,10 @@
 	{ "Cyrix 486S/DX",	CPUCLASS_486 },		/* CPU_CY486DX */
 };
 
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+int has_f00f_bug = 0;
+#endif
+
 void
 printcpuinfo(void)
 {
@@ -119,6 +123,14 @@
 				break;
 			case 0x500:
 				strcat(cpu_model, "Pentium"); /* nb no space */
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+				/*
+				 * XXX - If/when Intel fixes the bug, this
+				 * should also check the version of the
+				 * CPU, not just that it's a Pentium.
+				 */
+				has_f00f_bug = 1;
+#endif
 				break;
 			case 0x600:
 				strcat(cpu_model, "Pentium Pro");
diff -ur src/sys/i386/i386/machdep.c src/sys/i386/i386/machdep.c
--- src/sys/i386/i386/machdep.c	Thu Sep 25 08:50:53 1997
+++ src/sys/i386/i386/machdep.c	Wed Dec 24 11:15:57 1997
@@ -40,6 +40,7 @@
 
 #include "npx.h"
 #include "opt_sysvipc.h"
+#include "opt_cpu.h"
 #include "opt_ddb.h"
 #include "opt_bounce.h"
 #include "opt_machdep.h"
@@ -743,6 +744,11 @@
 struct gate_descriptor idt[NIDT];	/* interrupt descriptor table */
 union descriptor ldt[NLDT];		/* local descriptor table */
 
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+struct gate_descriptor *t_idt;
+int has_f00f_bug;
+#endif
+
 static struct i386tss dblfault_tss;
 static char dblfault_stack[PAGE_SIZE];
 
@@ -1360,6 +1366,41 @@
 	proc0.p_addr->u_pcb.pcb_flags = 0;
 	proc0.p_addr->u_pcb.pcb_cr3 = IdlePTD;
 }
+
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+void f00f_hack(void);
+SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL);
+
+void
+f00f_hack(void) {
+	struct region_descriptor r_idt;
+	unsigned char *tmp;
+	int i;
+	unsigned *pte;
+
+	if (!has_f00f_bug)
+		return;
+
+	printf("Intel Pentium F00F detected, installing workaround\n");
+
+	r_idt.rd_limit = sizeof(idt) - 1;
+
+	tmp = kmem_alloc(kernel_map, PAGE_SIZE * 2);
+	if (tmp == 0)
+		panic("kmem_alloc returned 0");
+	if (((unsigned int)tmp) & PAGE_SIZE - 1)
+		panic("kern_alloc returned non-page-aligned memory");
+	/* Put the first seven entries in the lower page */
+	t_idt = (struct gate_descriptor*)(tmp + PAGE_SIZE - (7*8));
+	bcopy(idt, t_idt, sizeof(idt));
+	r_idt.rd_base = (int)t_idt;
+	lidt(&r_idt);
+	if (vm_map_protect(kernel_map, tmp, tmp + PAGE_SIZE,
+			   VM_PROT_READ, FALSE) != KERN_SUCCESS)
+		panic("vm_map_protect failed");
+	return;
+}
+#endif /* NO_F00F_HACK */
 
 /*
  * The registers are in the frame; the frame is in the user area of
diff -ur src/sys/i386/i386/mem.c src/sys/i386/i386/mem.c
--- src/sys/i386/i386/mem.c	Fri Sep 27 06:25:06 1996
+++ src/sys/i386/i386/mem.c	Wed Dec 24 11:15:30 1997
@@ -169,6 +169,7 @@
 	int fmt;
 	struct proc *p;
 {
+	int error;
 	struct trapframe *fp;
 
 	switch (minor(dev)) {
@@ -179,6 +180,11 @@
 		return ENODEV;
 #endif
 	case 14:
+		error = suser(p->p_ucred, &p->p_acflag);
+		if (error != 0)
+			return (error);
+		if (securelevel > 0)
+			return (EPERM);
 		fp = (struct trapframe *)curproc->p_md.md_regs;
 		fp->tf_eflags |= PSL_IOPL;
 		break;
diff -ur src/sys/i386/i386/trap.c src/sys/i386/i386/trap.c
--- src/sys/i386/i386/trap.c	Wed Feb 12 23:51:53 1997
+++ src/sys/i386/i386/trap.c	Wed Dec 24 11:15:57 1997
@@ -42,6 +42,7 @@
  * 386 Trap and System call handling
  */
 
+#include "opt_cpu.h"
 #include "opt_ktrace.h"
 #include "opt_ddb.h"
 
@@ -133,6 +134,11 @@
 static void userret __P((struct proc *p, struct trapframe *frame,
 			 u_quad_t oticks));
 
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+extern struct gate_descriptor *t_idt;
+extern int has_f00f_bug;
+#endif
+
 static inline void
 userret(p, frame, oticks)
 	struct proc *p;
@@ -189,6 +195,9 @@
 	u_long eva;
 #endif
 
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+restart:
+#endif
 	type = frame.tf_trapno;
 	code = frame.tf_err;
 
@@ -239,6 +248,10 @@
 			i = trap_pfault(&frame, TRUE);
 			if (i == -1)
 				return;
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+			if (i == -2)
+				goto restart;
+#endif
 			if (i == 0)
 				goto out;
 
@@ -585,7 +598,18 @@
 	if (va >= KERNBASE) {
 		/*
 		 * Don't allow user-mode faults in kernel address space.
+		 * An exception:  if the faulting address is the invalid
+		 * instruction entry in the IDT, then the Intel Pentium
+		 * F00F bug workaround was triggered, and we need to
+		 * treat it is as an illegal instruction, and not a page
+		 * fault.
 		 */
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+		if ((eva == (unsigned int)&t_idt[6]) && has_f00f_bug) {
+			frame->tf_trapno = T_PRIVINFLT;
+			return -2;
+		}
+#endif
 		if (usermode)
 			goto nogo;
 
diff -ur src/sys/kern/vfs_bio.c src/sys/kern/vfs_bio.c
--- src/sys/kern/vfs_bio.c	Mon Sep  1 16:23:08 1997
+++ src/sys/kern/vfs_bio.c	Fri Mar 13 18:02:08 1998
@@ -18,7 +18,7 @@
  * 5. Modifications may be freely made to this file if the above 
conditions
  *    are met.
  *
- * $Id: vfs_bio.c,v 1.104.2.7 1997/09/01 23:23:08 tegge Exp $
+ * $Id: vfs_bio.c,v 1.104.2.8 1998/03/05 12:20:08 dg Exp $
  */
 
 /*
@@ -597,10 +597,6 @@
 		LIST_REMOVE(bp, b_hash);
 		LIST_INSERT_HEAD(&invalhash, bp, b_hash);
 		bp->b_dev = NODEV;
-		/*
-		 * Get rid of the kva allocation *now*
-		 */
-		bfreekva(bp);
 		if (needsbuffer) {
 			wakeup(&needsbuffer);
 			needsbuffer=0;
@@ -853,7 +849,7 @@
 static struct buf *
 getnewbuf(int slpflag, int slptimeo, int size, int maxsize)
 {
-	struct buf *bp;
+	struct buf *bp, *bp1;
 	int nbyteswritten = 0;
 	vm_offset_t addr;
 
@@ -981,11 +977,23 @@
 	if (maxsize != bp->b_kvasize) {
 		bfreekva(bp);
 		
+findkvaspace:
 		/*
 		 * See if we have buffer kva space
 		 */
 		if (vm_map_findspace(buffer_map,
 			vm_map_min(buffer_map), maxsize, &addr)) {
+			int tfree = 0;
+			for (bp1 = TAILQ_FIRST(&bufqueues[QUEUE_EMPTY]);
+				bp1 != NULL; bp1 = TAILQ_NEXT(bp1, b_freelist))
+				if (bp1->b_kvasize != 0) {
+					tfree += bp1->b_kvasize;
+					bremfree(bp1);
+					bfreekva(bp1);
+					brelse(bp1);
+					if (tfree >= maxsize)
+						goto findkvaspace;
+				}
 			bp->b_flags |= B_INVAL;
 			brelse(bp);
 			goto trytofreespace;
@@ -1842,7 +1850,7 @@
 		vm_ooffset_t sv, ev;
 		off = off - pageno * PAGE_SIZE;
 		sv = off + ((bp->b_validoff + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1));
-		ev = off + (bp->b_validend & ~(DEV_BSIZE - 1));
+		ev = off + ((bp->b_validend + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1));
 		soff = max(sv, soff);
 		eoff = min(ev, eoff);
 	}
diff -ur src/sys/kern/vfs_syscalls.c src/sys/kern/vfs_syscalls.c
--- src/sys/kern/vfs_syscalls.c	Tue Sep 30 23:23:48 1997
+++ src/sys/kern/vfs_syscalls.c	Wed Dec 24 11:15:12 1997
@@ -688,11 +688,13 @@
 	struct flock lf;
 	struct nameidata nd;
 
+	flags = FFLAGS(uap->flags);
+	if ((flags & FREAD + FWRITE) == 0)
+		return (EINVAL);
 	error = falloc(p, &nfp, &indx);
 	if (error)
 		return (error);
 	fp = nfp;
-	flags = FFLAGS(uap->flags);
 	cmode = ((uap->mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
 	p->p_dupfd = -indx - 1;			/* XXX check for fdopen */
diff -ur src/sys/miscfs/fdesc/fdesc_vnops.c src/sys/miscfs/fdesc/fdesc_v
nops.c
--- src/sys/miscfs/fdesc/fdesc_vnops.c	Sat Dec 21 11:04:28 1996
+++ src/sys/miscfs/fdesc/fdesc_vnops.c	Fri Jan  2 09:43:09 1998
@@ -409,11 +409,18 @@
 		}
 		break;
 
+	case DTYPE_PIPE:
 	case DTYPE_SOCKET:
-		error = soo_stat((struct socket *)fp->f_data, &stb);
+		if (fp->f_type == DTYPE_SOCKET)
+			error = soo_stat((struct socket *)fp->f_data, &stb);
+		else
+			error = pipe_stat((struct pipe *)fp->f_data, &stb);
 		if (error == 0) {
 			vattr_null(vap);
-			vap->va_type = VSOCK;
+			if (fp->f_type == DTYPE_SOCKET)
+				vap->va_type = VSOCK;
+			else
+				vap->va_type = VFIFO;
 			vap->va_mode = stb.st_mode;
 			vap->va_nlink = stb.st_nlink;
 			vap->va_uid = stb.st_uid;
@@ -557,6 +564,7 @@
 		error = VOP_SETATTR((struct vnode *) fp->f_data, ap->a_vap, ap->
a_cred, ap->a_p);
 		break;
 
+	case DTYPE_PIPE:
 	case DTYPE_SOCKET:
 		error = 0;
 		break;
diff -ur src/sys/net/if_ethersubr.c src/sys/net/if_ethersubr.c
--- src/sys/net/if_ethersubr.c	Tue Sep 30 05:29:00 1997
+++ src/sys/net/if_ethersubr.c	Wed Dec 24 11:52:22 1997
@@ -194,21 +194,46 @@
 #endif
 #ifdef NETATALK
 	case AF_APPLETALK:
-            if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
+	    {
+		struct sockaddr_at *sat = (struct sockaddr_at *)dst;
+
+		/*
+		 * super hack..
+		 * Most of this loopback code should move into the appletalk
+		 * code, but it's here for now.. remember to move it! [JRE]
+		 * This may not get the same interface we started with
+		 * fix asap. XXX
+		 */
+		aa = at_ifawithnet( sat );
+		if (aa == NULL) {
+			goto bad;
+		}
+		if( aa->aa_ifa.ifa_ifp != ifp ) {
+			(*aa->aa_ifa.ifa_ifp->if_output)(aa->aa_ifa.ifa_ifp,
+							m,dst,rt);
+		}
+		if (((sat->sat_addr.s_net == ATADDR_ANYNET)
+		  && (sat->sat_addr.s_node == ATADDR_ANYNODE))
+		|| ((sat->sat_addr.s_net == aa->aa_addr.sat_addr.s_net )
+		  && (sat->sat_addr.s_node == aa->aa_addr.sat_addr.s_node))) {
+			(void) looutput(ifp, m, dst, rt);
+			return(0);
+		}
+
+        	if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
 #ifdef NETATALKDEBUG
-                extern char *prsockaddr(struct sockaddr *);
-                printf("aarpresolv: failed for %s\n", prsockaddr(dst));
+                	extern char *prsockaddr(struct sockaddr *);
+                	printf("aarpresolv: failed for %s\n", 
prsockaddr(dst));
 #endif NETATALKDEBUG
-                return (0);
-            }
-	    /*
-	     * ifaddr is the first thing in at_ifaddr
-	     */
-	    if ((aa = (struct at_ifaddr *)at_ifawithnet(
-			(struct sockaddr_at *)dst, ifp->if_addrlist))
-		== 0)
-		goto bad;
-	    
+                	return (0);
+        	}
+
+		/*
+		 * If broadcasting on a simplex interface, loopback a copy
+		 */
+		if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
+			mcopy = m_copy(m, 0, (int)M_COPYALL);
+	    }
 	    /*
 	     * In the phase 2 case, we need to prepend an mbuf for the llc 
header.
 	     * Since we must preserve the value of m, which is passed to us by
diff -ur src/sys/netatalk/aarp.c src/sys/netatalk/aarp.c
--- src/sys/netatalk/aarp.c	Thu Aug 29 16:16:29 1996
+++ src/sys/netatalk/aarp.c	Wed Dec 24 11:52:22 1997
@@ -94,30 +94,24 @@
  * the given network.. remember to take netranges into
  * consideration.
  */
-struct ifaddr *
-at_ifawithnet( sat, ifa )
-    struct sockaddr_at	*sat;
-    struct ifaddr	*ifa;
+struct at_ifaddr *
+at_ifawithnet(struct sockaddr_at  *sat )
 {
+    struct at_ifaddr	*aa;
     struct sockaddr_at	*sat2;
-    struct netrange	*nr;
 
-    for (; ifa; ifa = ifa->ifa_next ) {
-	if ( ifa->ifa_addr->sa_family != AF_APPLETALK ) {
-	    continue;
-	}
-	sat2 = satosat( ifa->ifa_addr );
-	if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) {
-	    break;
+	for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+		sat2 = &(aa->aa_addr);
+		if ( sat2->sat_addr.s_net == sat->sat_addr.s_net ) {
+	    		break;
+		}
+		if( (aa->aa_flags & AFA_PHASE2 )
+	 	&& (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net))
+	 	&& (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net))) {
+			break;
+		}
 	}
-	nr = (struct netrange *)(sat2->sat_zero);
-	if( (nr->nr_phase == 2 )
-	 && (nr->nr_firstnet <= sat->sat_addr.s_net)
-	 && (nr->nr_lastnet >= sat->sat_addr.s_net)) {
-		break;
-	}
-    }
-    return( ifa );
+	return( aa );
 }
 
 static void
@@ -155,8 +149,7 @@
      * interface with the same address as we're looking for. If the
      * net is phase 2, generate an 802.2 and SNAP header.
      */
-    if (( aa = (struct at_ifaddr *)at_ifawithnet( sat, ac->
ac_if.if_addrlist ))
-	    == NULL ) {
+    if (( aa = at_ifawithnet( sat )) == NULL ) {
 	m_freem( m );
 	return;
     }
@@ -213,8 +206,8 @@
     int			s;
 
     if ( at_broadcast( destsat )) {
-	if (( aa = (struct at_ifaddr *)at_ifawithnet( destsat,
-		((struct ifnet *)ac)->if_addrlist )) == NULL ) {
+	m->m_flags |= M_BCAST;
+	if (( aa = at_ifawithnet( destsat )) == NULL ) {
 	    m_freem( m );
 	    return( 0 );
 	}
@@ -325,8 +318,7 @@
 	sat.sat_len = sizeof(struct sockaddr_at);
 	sat.sat_family = AF_APPLETALK;
 	sat.sat_addr.s_net = net;
-	if (( aa = (struct at_ifaddr *)at_ifawithnet( &sat,
-		ac->ac_if.if_addrlist )) == NULL ) {
+	if (( aa = at_ifawithnet( &sat )) == NULL ) {
 	    m_freem( m );
 	    return;
 	}
diff -ur src/sys/netatalk/at_control.c src/sys/netatalk/at_control.c
--- src/sys/netatalk/at_control.c	Sun Oct  5 14:41:06 1997
+++ src/sys/netatalk/at_control.c	Wed Dec 24 11:52:22 1997
@@ -882,10 +882,10 @@
 		 */
 		if ((addr->sat_addr.s_net == gw->sat_addr.s_net)
 		|| ((addr->sat_range.r_netrange.nr_lastnet)
-		  && (gw->sat_addr.s_net
-				>= addr->sat_range.r_netrange.nr_firstnet )
-		  && (gw->sat_addr.s_net
-				<= addr->sat_range.r_netrange.nr_lastnet ))) {
+		  && (ntohs(gw->sat_addr.s_net)
+			>= ntohs(addr->sat_range.r_netrange.nr_firstnet ))
+		  && (ntohs(gw->sat_addr.s_net)
+			<= ntohs(addr->sat_range.r_netrange.nr_lastnet )))) {
 			return 1;
 		} 
 		break;
diff -ur src/sys/netatalk/at_extern.h src/sys/netatalk/at_extern.h
--- src/sys/netatalk/at_extern.h	Thu May 23 18:35:23 1996
+++ src/sys/netatalk/at_extern.h	Wed Dec 24 11:52:22 1997
@@ -24,8 +24,7 @@
 					struct mbuf  *addr,
 					struct mbuf *rights));
 extern void	ddp_init	__P((void ));
-extern struct ifaddr *at_ifawithnet	__P((struct sockaddr_at *,
-						struct ifaddr *));
+extern struct at_ifaddr *at_ifawithnet	__P((struct sockaddr_at *));
 #ifdef	_NETATALK_DDP_VAR_H_
 extern int	ddp_output	__P(( struct ddpcb *ddp, struct mbuf *m));
 #endif
diff -ur src/sys/netatalk/ddp_input.c src/sys/netatalk/ddp_input.c
--- src/sys/netatalk/ddp_input.c	Tue Sep 10 01:23:11 1996
+++ src/sys/netatalk/ddp_input.c	Wed Dec 24 11:52:22 1997
@@ -41,6 +41,9 @@
     struct at_ifaddr	*aa;
     int			s;
 
+    /*
+     * First pull off all the phase 2 packets.
+     */
     for (;;) {
 	s = splimp();
 
@@ -53,19 +56,12 @@
 	}
 
 	ifp = m->m_pkthdr.rcvif;
-	for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
-	    if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 )) {
-		break;
-	    }
-	}
-	if ( aa == NULL ) {		/* ifp not an appletalk interface */
-	    m_freem( m );
-	    continue;
-	}
-
 	ddp_input( m, ifp, (struct elaphdr *)NULL, 2 );
     }
 
+    /*
+     * Then pull off all the phase 1 packets.
+     */
     for (;;) {
 	s = splimp();
 
@@ -78,15 +74,6 @@
 	}
 
 	ifp = m->m_pkthdr.rcvif;
-	for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
-	    if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
-		break;
-	    }
-	}
-	if ( aa == NULL ) {		/* ifp not an appletalk interface */
-	    m_freem( m );
-	    continue;
-	}
 
 	if ( m->m_len < SZ_ELAPHDR &&
 		(( m = m_pullup( m, SZ_ELAPHDR )) == 0 )) {
@@ -94,6 +81,9 @@
 	    continue;
 	}
 
+	/*
+	 * this seems a little dubios, but I don't know phase 1 so leave it.
+	 */
 	elhp = mtod( m, struct elaphdr *);
 	m_adj( m, SZ_ELAPHDR );
 
@@ -127,7 +117,14 @@
     u_short		cksum = 0;
 
     bzero( (caddr_t)&from, sizeof( struct sockaddr_at ));
+    bzero( (caddr_t)&to, sizeof( struct sockaddr_at ));
     if ( elh ) {
+	/*
+	 * Extract the information in the short header.
+	 * netowrk information is defaulted to ATADDR_ANYNET
+	 * and node information comes from the elh info.
+	 * We must be phase 1.
+	 */
 	ddpstat.ddps_short++;
 
 	if ( m->m_len < sizeof( struct ddpshdr ) &&
@@ -148,18 +145,32 @@
 	from.sat_addr.s_node = elh->el_snode;
 	from.sat_port = ddps.dsh_sport;
 
+	/* 
+	 * Make sure that we point to the phase1 ifaddr info 
+	 * and that it's valid for this packet.
+	 */
 	for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
-	    if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 ) == 0 &&
-		    ( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node ||
-		    to.sat_addr.s_node == ATADDR_BCAST )) {
+	    if ( (aa->aa_ifp == ifp)
+	    && ( (aa->aa_flags & AFA_PHASE2) == 0)
+	    && ( (to.sat_addr.s_node == AA_SAT( aa )->sat_addr.s_node)
+	      || (to.sat_addr.s_node == ATADDR_BCAST))) {
 		break;
 	    }
 	}
+	/* 
+	 * maybe we got a broadcast not meant for us.. ditch it.
+	 */
 	if ( aa == NULL ) {
 	    m_freem( m );
 	    return;
 	}
     } else {
+	/*
+	 * There was no 'elh' passed on. This could still be
+	 * either phase1 or phase2.
+	 * We have a long header, but we may be running on a pahse 1 net.
+	 * Extract out all the info regarding this packet's src & dst.
+	 */
 	ddpstat.ddps_long++;
 
 	if ( m->m_len < sizeof( struct ddpehdr ) &&
@@ -185,6 +196,18 @@
 	to.sat_port = ddpe.deh_dport;
 
 	if ( to.sat_addr.s_net == ATADDR_ANYNET ) {
+	    /*
+	     * The TO address doesn't specify a net,
+	     * So by definition it's for this net.
+	     * Try find ifaddr info with the right phase, 
+	     * the right interface, and either to our node, a bradcast,
+	     * or looped back (though that SHOULD be covered in the other
+	     * cases).
+	     *
+	     * XXX If we have multiple interfaces, then the first with
+	     * this node number will match (which may NOT be what we want,
+	     * but it's probably safe in 99.999% of cases.
+	     */
 	    for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
 		if ( phase == 1 && ( aa->aa_flags & AFA_PHASE2 )) {
 		    continue;
@@ -192,27 +215,47 @@
 		if ( phase == 2 && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
 		    continue;
 		}
-		if ( aa->aa_ifp == ifp &&
-			( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node ||
-			to.sat_addr.s_node == ATADDR_BCAST ||
-			( ifp->if_flags & IFF_LOOPBACK ))) {
+		if ( (aa->aa_ifp == ifp)
+		&& ( (to.sat_addr.s_node == AA_SAT( aa )->sat_addr.s_node)
+		  || (to.sat_addr.s_node == ATADDR_BCAST)
+		  || (ifp->if_flags & IFF_LOOPBACK))) {
 		    break;
 		}
 	    }
 	} else {
+	    /* 
+	     * A destination network was given. We just try to find 
+	     * which ifaddr info matches it.
+	     */
 	    for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
+		/*
+		 * This is a kludge. Accept packets that are
+		 * for any router on a local netrange.
+		 */
 		if ( to.sat_addr.s_net == aa->aa_firstnet &&
 			to.sat_addr.s_node == 0 ) {
 		    break;
 		}
-		if (( ntohs( to.sat_addr.s_net ) < ntohs( aa->aa_firstnet ) ||
-			ntohs( to.sat_addr.s_net ) > ntohs( aa->aa_lastnet )) &&
-			( ntohs( to.sat_addr.s_net ) < ntohs( 0xff00 ) ||
-			ntohs( to.sat_addr.s_net ) > ntohs( 0xfffe ))) {
+		/*
+		 * Don't use ifaddr info for which we are totally outside the
+		 * netrange, and it's not a startup packet.
+		 * Startup packets are always implicitly allowed on to
+		 * the next test.
+		 */
+		if ((( ntohs( to.sat_addr.s_net ) < ntohs( aa->aa_firstnet ))
+		    || (ntohs( to.sat_addr.s_net ) > ntohs( aa->aa_lastnet )))
+		 && (( ntohs( to.sat_addr.s_net ) < ntohs( 0xff00 ))
+		    || (ntohs( to.sat_addr.s_net ) > ntohs( 0xfffe )))) {
 		    continue;
 		}
-		if ( to.sat_addr.s_node != AA_SAT( aa )->sat_addr.s_node &&
-			to.sat_addr.s_node != ATADDR_BCAST ) {
+
+		/*
+		 * Don't record a match either if we just don't have a match
+		 * in the node address. This can have if the interface
+		 * is in promiscuous mode for example.
+		 */
+		if (( to.sat_addr.s_node != AA_SAT( aa )->sat_addr.s_node)
+		&& (to.sat_addr.s_node != ATADDR_BCAST) ) {
 		    continue;
 		}
 		break;
@@ -236,43 +279,75 @@
     }
 
     /*
-     * XXX Should we deliver broadcasts locally, also, or rely on the
-     * link layer to give us a copy?  For the moment, the latter.
+     * If it aint for a net on any of our interfaces,
+     * or it IS for a net on a different interface than it came in on,
+     * (and it is not looped back) then consider if we shoulf forward 
it.
+     * As we a re not really a router this is a bit cheaky, but it may 
be
+     * useful some day.
      */
-    if ( aa == NULL || ( to.sat_addr.s_node == ATADDR_BCAST &&
-	    aa->aa_ifp != ifp && ( ifp->if_flags & IFF_LOOPBACK ) == 0 )) {
+    if ( (aa == NULL)
+    || ( (to.sat_addr.s_node == ATADDR_BCAST)
+      && (aa->aa_ifp != ifp)
+      && (( ifp->if_flags & IFF_LOOPBACK ) == 0 ))) {
+	/* 
+	 * If we've explicitly disabled it, don't route anything
+	 */
 	if ( ddp_forward == 0 ) {
 	    m_freem( m );
 	    return;
 	}
-	if ( forwro.ro_rt && ( satosat( &forwro.ro_dst )->sat_addr.s_net !=
-		to.sat_addr.s_net ||
-		satosat( &forwro.ro_dst )->sat_addr.s_node !=
-		to.sat_addr.s_node )) {
+	/* 
+	 * If the cached forwarding route is still valid, use it.
+	 */
+	if ( forwro.ro_rt
+	&& ( satosat(&forwro.ro_dst)->sat_addr.s_net != to.sat_addr.s_net
+	  || satosat(&forwro.ro_dst)->sat_addr.s_node != to.sat_addr.s_node 
)) {
 	    RTFREE( forwro.ro_rt );
 	    forwro.ro_rt = (struct rtentry *)0;
 	}
-	if ( forwro.ro_rt == (struct rtentry *)0 ||
-	     forwro.ro_rt->rt_ifp == (struct ifnet *)0 ) {
+
+	/*
+	 * If we don't have a cached one (any more) or it's useless,
+	 * Then get a new route.
+	 * XXX this could cause a 'route leak'. check this!
+	 */
+	if ( forwro.ro_rt == (struct rtentry *)0
+	|| forwro.ro_rt->rt_ifp == (struct ifnet *)0 ) {
 	    forwro.ro_dst.sa_len = sizeof( struct sockaddr_at );
 	    forwro.ro_dst.sa_family = AF_APPLETALK;
-	    satosat( &forwro.ro_dst )->sat_addr.s_net = to.sat_addr.s_net;
-	    satosat( &forwro.ro_dst )->sat_addr.s_node = to.sat_addr.s_node;
-	    rtalloc( &forwro );
+	    satosat(&forwro.ro_dst)->sat_addr.s_net = to.sat_addr.s_net;
+	    satosat(&forwro.ro_dst)->sat_addr.s_node = to.sat_addr.s_node;
+	    rtalloc(&forwro);
 	}
 
-	if ( to.sat_addr.s_net != satosat( &forwro.ro_dst )->sat_addr.s_net &&
-		ddpe.deh_hops == DDP_MAXHOPS ) {
+	/* 
+	 * If it's not going to get there on this hop, and it's
+	 * already done too many hops, then throw it away.
+	 */
+	if ( (to.sat_addr.s_net != satosat( &forwro.ro_dst )->sat_addr.s_net)
+	&& (ddpe.deh_hops == DDP_MAXHOPS) ) {
 	    m_freem( m );
 	    return;
 	}
 
-	if ( ddp_firewall &&
-		( forwro.ro_rt == NULL || forwro.ro_rt->rt_ifp != ifp )) {
+	/*
+	 * A ddp router might use the same interface
+	 * to forward the packet, which this would not effect.
+	 * Don't allow packets to cross from one interface to another however.
+	 */
+	if ( ddp_firewall
+	&& ( (forwro.ro_rt == NULL)
+	  || (forwro.ro_rt->rt_ifp != ifp))) {
 	    m_freem( m );
 	    return;
 	}
 
+	/*
+	 * Adjust the header.
+	 * If it was a short header then it would have not gotten here,
+	 * so we can assume there is room to drop the header in.
+	 * XXX what about promiscuous mode, etc...
+	 */
 	ddpe.deh_hops++;
 	ddpe.deh_bytes = htonl( ddpe.deh_bytes );
 	bcopy( (caddr_t)&ddpe, (caddr_t)deh, sizeof( u_short )); /* XXX deh? 
*/
@@ -284,9 +359,16 @@
 	return;
     }
 
+    /*
+     * It was for us, and we have an ifaddr to use with it.
+     */
     from.sat_len = sizeof( struct sockaddr_at );
     from.sat_family = AF_APPLETALK;
 
+    /* 
+     * We are no longer interested in the link layer.
+     * so cut it off.
+     */
     if ( elh ) {
 	m_adj( m, sizeof( struct ddpshdr ));
     } else {
@@ -298,21 +380,36 @@
 	m_adj( m, sizeof( struct ddpehdr ));
     }
 
+    /* 
+     * Search for ddp protocol control blocks that match these
+     * addresses. 
+     */
     if (( ddp = ddp_search( &from, &to, aa )) == NULL ) {
 	m_freem( m );
 	return;
     }
 
+    /* 
+     * If we found one, deliver th epacket to the socket
+     */
     if ( sbappendaddr( &ddp->ddp_socket->so_rcv, (struct sockaddr 
*)&from,
 	    m, (struct mbuf *)0 ) == 0 ) {
+	/* 
+	 * If the socket is full (or similar error) dump the packet.
+	 */
 	ddpstat.ddps_nosockspace++;
 	m_freem( m );
 	return;
     }
+    /*
+     * And wake up whatever might be waiting for it
+     */
     sorwakeup( ddp->ddp_socket );
 }
 
 #if 0
+/* As if we haven't got enough of this sort of think floating
+around the kernel :) */
 
 #define BPXLEN	48
 #define BPALEN	16
diff -ur src/sys/netatalk/ddp_output.c src/sys/netatalk/ddp_output.c
--- src/sys/netatalk/ddp_output.c	Sun Oct  5 14:41:06 1997
+++ src/sys/netatalk/ddp_output.c	Wed Dec 24 11:52:23 1997
@@ -128,11 +128,11 @@
     if ( (ro->ro_rt != NULL)
     && ( ro->ro_rt->rt_ifa )
     && ( ifp = ro->ro_rt->rt_ifa->ifa_ifp )) {
-	net = satosat(ro->ro_rt->rt_gateway)->sat_addr.s_net;
+	net = ntohs(satosat(ro->ro_rt->rt_gateway)->sat_addr.s_net);
 	for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
 	    if (((net == 0) || (aa->aa_ifp == ifp)) &&
-		    ntohs( net ) >= ntohs( aa->aa_firstnet ) &&
-		    ntohs( net ) <= ntohs( aa->aa_lastnet )) {
+		    net >= ntohs( aa->aa_firstnet ) &&
+		    net <= ntohs( aa->aa_lastnet )) {
 		break;
 	    }
 	}
diff -ur src/sys/netinet/in.h src/sys/netinet/in.h
--- src/sys/netinet/in.h	Mon Nov 11 15:40:37 1996
+++ src/sys/netinet/in.h	Thu Feb 26 17:20:46 1998
@@ -301,7 +301,8 @@
 #define	IPCTL_DIRECTEDBROADCAST	9	/* may re-broadcast received packets 
*/
 #define IPCTL_INTRQMAXLEN	10	/* max length of netisr queue */
 #define IPCTL_INTRQDROPS	11	/* number of netisr q drops */
-#define	IPCTL_MAXID		12
+#define	IPCTL_ACCEPTSOURCEROUTE	13	/* may accept source routed packets 
*/
+#define	IPCTL_MAXID		13
 
 #define	IPCTL_NAMES { \
 	{ 0, 0 }, \
@@ -316,6 +317,7 @@
  	{ "directed-broadcast", CTLTYPE_INT }, \
 	{ "intr-queue-maxlen", CTLTYPE_INT }, \
 	{ "intr-queue-drops", CTLTYPE_INT }, \
+	{ "accept_sourceroute", CTLTYPE_INT }, \
 }
 
 
diff -ur src/sys/netinet/ip_fw.c src/sys/netinet/ip_fw.c
--- src/sys/netinet/ip_fw.c	Sat Aug 23 07:31:52 1997
+++ src/sys/netinet/ip_fw.c	Wed Dec 24 11:51:59 1997
@@ -576,23 +576,24 @@
 		  {
 			struct tcphdr *const tcp =
 				(struct tcphdr *) ((u_long *)ip + ip->ip_hl);
-			struct tcpiphdr ti;
+			struct tcpiphdr ti, *const tip = (struct tcpiphdr *) ip;
 
 			if (offset != 0 || (tcp->th_flags & TH_RST))
 				break;
 			ti.ti_i = *((struct ipovly *) ip);
 			ti.ti_t = *tcp;
-			NTOHL(ti.ti_seq);
-			NTOHL(ti.ti_ack);
-			ti.ti_len = ip->ip_len - hlen - (ti.ti_off << 2);
+			bcopy(&ti, ip, sizeof(ti));
+			NTOHL(tip->ti_seq);
+			NTOHL(tip->ti_ack);
+			tip->ti_len = ip->ip_len - hlen - (tip->ti_off << 2);
 			if (tcp->th_flags & TH_ACK) {
-				tcp_respond(NULL, &ti, *m,
+				tcp_respond(NULL, tip, *m,
 				    (tcp_seq)0, ntohl(tcp->th_ack), TH_RST);
 			} else {
 				if (tcp->th_flags & TH_SYN)
-					ti.ti_len++;
-				tcp_respond(NULL, &ti, *m, ti.ti_seq
-				    + ti.ti_len, (tcp_seq)0, TH_RST|TH_ACK);
+					tip->ti_len++;
+				tcp_respond(NULL, tip, *m, tip->ti_seq
+				    + tip->ti_len, (tcp_seq)0, TH_RST|TH_ACK);
 			}
 			*m = NULL;
 			break;
diff -ur src/sys/netinet/ip_input.c src/sys/netinet/ip_input.c
--- src/sys/netinet/ip_input.c	Mon Sep 15 16:10:55 1997
+++ src/sys/netinet/ip_input.c	Thu Feb 26 17:20:46 1998
@@ -94,6 +94,10 @@
 static int	ip_dosourceroute = 0;
 SYSCTL_INT(_net_inet_ip, IPCTL_SOURCEROUTE, sourceroute, CTLFLAG_RW,
 	&ip_dosourceroute, 0, "");
+
+static int	ip_acceptsourceroute = 0;
+SYSCTL_INT(_net_inet_ip, IPCTL_ACCEPTSOURCEROUTE, accept_sourceroute,
+	CTLFLAG_RW, &ip_acceptsourceroute, 0, "");
 #ifdef DIAGNOSTIC
 static int	ipprintfs = 0;
 #endif
@@ -923,6 +927,8 @@
 					code = ICMP_UNREACH_SRCFAIL;
 					goto bad;
 				}
+				if (!ip_dosourceroute)
+					goto nosourcerouting;
 				/*
 				 * Loose routing, and not at next destination
 				 * yet; nothing to do except forward.
@@ -934,14 +940,17 @@
 				/*
 				 * End of source route.  Should be for us.
 				 */
+				if (!ip_acceptsourceroute)
+					goto nosourcerouting;
 				save_rte(cp, ip->ip_src);
 				break;
 			}
 
 			if (!ip_dosourceroute) {
 				char buf[4*sizeof "123"];
-				strcpy(buf, inet_ntoa(ip->ip_dst));
 
+nosourcerouting:
+				strcpy(buf, inet_ntoa(ip->ip_dst));
 				log(LOG_WARNING, 
 				    "attempted source route from %s to %s\n",
 				    inet_ntoa(ip->ip_src), buf);
@@ -1056,7 +1065,7 @@
 			ipt->ipt_ptr += sizeof(n_time);
 		}
 	}
-	if (forward) {
+	if (forward && ipforwarding) {
 		ip_forward(m, 1);
 		return (1);
 	}
diff -ur src/sys/netinet/tcp_input.c src/sys/netinet/tcp_input.c
--- src/sys/netinet/tcp_input.c	Sat Oct  4 01:54:12 1997
+++ src/sys/netinet/tcp_input.c	Thu Mar 12 19:39:56 1998
@@ -614,6 +614,7 @@
 	 * If the state is LISTEN then ignore segment if it contains an RST.
 	 * If the segment contains an ACK then it is bad and send a RST.
 	 * If it does not contain a SYN then it is not interesting; drop it.
+	 * If it is from this socket, drop it, it must be forged.
 	 * Don't bother responding if the destination was a broadcast.
 	 * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
 	 * tp->iss, and send a segment:
@@ -633,6 +634,9 @@
 			goto dropwithreset;
 		if ((tiflags & TH_SYN) == 0)
 			goto drop;
+		if ((ti->ti_dport == ti->ti_sport) &&
+		    (ti->ti_dst.s_addr == ti->ti_src.s_addr))
+			goto drop;
 		/*
 		 * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
 		 * in_broadcast() should never return true on a received
@@ -752,6 +756,23 @@
 		}
 
 	/*
+	 * If the state is SYN_RECEIVED:
+	 *	if seg contains SYN/ACK, send a RST.
+	 *	if seg contains an ACK, but not for our SYN/ACK, send a RST.
+	 */
+	case TCPS_SYN_RECEIVED:
+		if (tiflags & TH_ACK) {
+			if (tiflags & TH_SYN) {
+				tcpstat.tcps_badsyn++;
+				goto dropwithreset;
+			}
+			if (SEQ_LEQ(ti->ti_ack, tp->snd_una) ||
+			    SEQ_GT(ti->ti_ack, tp->snd_max))
+				goto dropwithreset;
+		}
+		break;
+
+	/*
 	 * If the state is SYN_SENT:
 	 *	if seg contains an ACK, but not for our SYN, drop the input.
 	 *	if seg contains a RST, then drop the connection.
@@ -1166,14 +1187,11 @@
 	switch (tp->t_state) {
 
 	/*
-	 * In SYN_RECEIVED state if the ack ACKs our SYN then enter
-	 * ESTABLISHED state and continue processing, otherwise
-	 * send an RST.
+	 * In SYN_RECEIVED state, the ack ACKs our SYN, so enter
+	 * ESTABLISHED state and continue processing.
+	 * The ACK was checked above.
 	 */
 	case TCPS_SYN_RECEIVED:
-		if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
-		    SEQ_GT(ti->ti_ack, tp->snd_max))
-			goto dropwithreset;
 
 		tcpstat.tcps_connects++;
 		soisconnected(so);
diff -ur src/sys/netinet/tcp_subr.c src/sys/netinet/tcp_subr.c
--- src/sys/netinet/tcp_subr.c	Tue Sep 30 09:25:11 1997
+++ src/sys/netinet/tcp_subr.c	Wed Dec 24 11:51:59 1997
@@ -168,6 +168,8 @@
  *
  * In any case the ack and sequence number of the transmitted
  * segment are as specified by the parameters.
+ *
+ * NOTE: If m != NULL, then ti must point to *inside* the mbuf.
  */
 void
 tcp_respond(tp, ti, m, ack, seq, flags)
diff -ur src/sys/vm/vm_map.c src/sys/vm/vm_map.c
--- src/sys/vm/vm_map.c	Mon Mar 24 20:54:26 1997
+++ src/sys/vm/vm_map.c	Sat Dec 27 23:39:36 1997
@@ -61,7 +61,7 @@
  * any improvements or extensions that they make and grant Carnegie the
  * rights to redistribute these changes.
  *
- * $Id: vm_map.c,v 1.57.2.4 1997/03/25 04:54:26 dyson Exp $
+ * $Id: vm_map.c,v 1.57.2.5 1997/11/04 09:02:38 dyson Exp $
  */
 
 /*
@@ -283,9 +283,9 @@
 
 	if (kmem_map == NULL) {
 		result = kmap_free;
-		kmap_free = (vm_map_t) result->header.next;
 		if (result == NULL)
 			panic("vm_map_create: out of maps");
+		kmap_free = (vm_map_t) result->header.next;
 	} else
 		MALLOC(result, vm_map_t, sizeof(struct vm_map),
 		    M_VMMAP, M_WAITOK);
@@ -935,6 +935,23 @@
 
 	vm_map_simplify_entry(map, entry);
 
+	/*
+	 * If there is no object backing this entry, we might as well create
+	 * one now.  If we defer it, an object can get created after the map
+	 * is clipped, and individual objects will be created for the split-up
+	 * map.  This is a bit of a hack, but is also about the best place to
+	 * put this improvement.
+	 */
+
+	if (entry->object.vm_object == NULL) {
+			vm_object_t object;
+
+			object = vm_object_allocate(OBJT_DEFAULT,
+					OFF_TO_IDX(entry->end - entry->start));
+			entry->object.vm_object = object;
+			entry->offset = 0;
+	}
+
 	new_entry = vm_map_entry_create(map);
 	*new_entry = *entry;
 
@@ -977,6 +994,23 @@
 	register vm_map_entry_t new_entry;
 
 	/*
+	 * If there is no object backing this entry, we might as well create
+	 * one now.  If we defer it, an object can get created after the map
+	 * is clipped, and individual objects will be created for the split-up
+	 * map.  This is a bit of a hack, but is also about the best place to
+	 * put this improvement.
+	 */
+
+	if (entry->object.vm_object == NULL) {
+			vm_object_t object;
+
+			object = vm_object_allocate(OBJT_DEFAULT,
+					OFF_TO_IDX(entry->end - entry->start));
+			entry->object.vm_object = object;
+			entry->offset = 0;
+	}
+
+	/*
 	 * Create a new entry and insert it AFTER the specified entry
 	 */
 
@@ -1174,10 +1208,12 @@
 #undef	max
 #undef	MASK
 		}
+
+		vm_map_simplify_entry(map, current);
+
 		current = current->next;
 	}
 
-	vm_map_simplify_entry(map, entry);
 	vm_map_unlock(map);
 	return (KERN_SUCCESS);
 }
@@ -1455,8 +1491,7 @@
 			}
 
 			lock_clear_recursive(&map->lock);
-			vm_map_unlock(map);
-			vm_map_lock(map);
+			lock_read_to_write(&map->lock);
 
 			goto rescan;
 		}
diff -ur src/sys/vm/vm_mmap.c src/sys/vm/vm_mmap.c
--- src/sys/vm/vm_mmap.c	Mon Mar 24 20:54:29 1997
+++ src/sys/vm/vm_mmap.c	Thu Mar 12 19:33:04 1998
@@ -157,6 +157,9 @@
 	vm_prot_t prot, maxprot;
 	caddr_t handle;
 	int flags, error;
+	int disablexworkaround;
+  
+  	addr = (vm_offset_t) uap->addr;
 
 	prot = uap->prot & VM_PROT_ALL;
 	flags = uap->flags;
@@ -230,6 +233,26 @@
 			flags |= MAP_ANON;
 		} else {
 			/*
+			 * cdevs does not provide private mappings of any kind.
+			 */
+			/*
+			 * However, for XIG X server to continue to work,
+			 * we should allow the superuser to do it anyway.
+			 * We only allow it at securelevel < 1.
+			 * (Because the XIG X server writes directly to video
+			 * memory via /dev/mem, it should never work at any
+			 * other securelevel.
+			 * XXX this will have to go
+			 */
+			if (securelevel >= 1)
+				disablexworkaround = 1;
+			else
+				disablexworkaround = suser(p->p_ucred,
+							   &p->p_acflag);
+			if (vp->v_type == VCHR && disablexworkaround &&
+				(flags & (MAP_PRIVATE|MAP_COPY)))
+				 return (EINVAL);
+			/*
 			 * Ensure that file and memory protections are
 			 * compatible.  Note that we only worry about
 			 * writability if mapping is shared; in this case,
@@ -243,12 +266,20 @@
 				maxprot |= VM_PROT_READ;
 			else if (prot & PROT_READ)
 				return (EACCES);
-			if (flags & MAP_SHARED) {
-				if (fp->f_flag & FWRITE)
-					maxprot |= VM_PROT_WRITE;
-				else if (prot & PROT_WRITE)
-					return (EACCES);
-			} else
+			/*
+			 * If we are sharing potential changes (either via
+			 * MAP_SHARED or via the implicit sharing of character
+			 * device mappings), and we are trying to get write
+			 * permission although we opened it without asking
+			 * for it, bail out.  Check for superuser, only if
+			 * we're at securelevel < 1, to allow the XIG X server
+			 * to continue to work.
+			 */
+			if (((flags & MAP_SHARED) != 0 ||
+				(vp->v_type == VCHR && disablexworkaround)) &&
+				(fp->f_flag & FWRITE) == 0 && (prot & PROT_WRITE) != 0)
+				return (EACCES);
+			else
 				maxprot |= VM_PROT_WRITE;
 			handle = (caddr_t) vp;
 		}
diff -ur src/sys/vm/vm_page.c src/sys/vm/vm_page.c
--- src/sys/vm/vm_page.c	Mon Mar 24 20:54:35 1997
+++ src/sys/vm/vm_page.c	Sat Dec 27 22:56:18 1997
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)vm_page.c	7.4 (Berkeley) 5/7/91
- *	$Id: vm_page.c,v 1.69.2.3 1997/03/25 04:54:35 dyson Exp $
+ *	$Id: vm_page.c,v 1.69.2.5 1997/11/06 04:33:01 dyson Exp $
  */
 
 /*
@@ -577,7 +577,7 @@
 		TAILQ_REMOVE(pq->pl, m, pageq);
 		--(*pq->cnt);
 		--(*pq->lcnt);
-		if ((m->queue - m->pc) == PQ_CACHE) {
+		if ((queue - m->pc) == PQ_CACHE) {
 			if ((cnt.v_cache_count + cnt.v_free_count) <
 				(cnt.v_free_reserved + cnt.v_cache_min))
 				pagedaemon_wakeup();
@@ -600,7 +600,7 @@
 
 	for(j = 0; j < PQ_L1_SIZE; j++) {
 		for(i = (PQ_L2_SIZE/2) - (PQ_L1_SIZE - 1);
-			i >= 0;
+			(i+j) >= 0;
 			i -= PQ_L1_SIZE) {
 			hindex = (index + (i+j)) & PQ_L2_MASK;
 			m = TAILQ_FIRST(vm_page_queues[basequeue + hindex].pl);
diff -ur src/sys/vm/vnode_pager.c src/sys/vm/vnode_pager.c
--- src/sys/vm/vnode_pager.c	Wed May 28 11:26:46 1997
+++ src/sys/vm/vnode_pager.c	Wed Dec 24 11:54:40 1997
@@ -231,10 +231,12 @@
 	blocksperpage = 0;
 	if (pagesperblock > 0) {
 		reqblock = pindex / pagesperblock;
-	} else {
+	} else if (bsize > 0)  {
 		blocksperpage = (PAGE_SIZE / bsize);
 		reqblock = pindex * blocksperpage;
-	}
+	} else
+		return FALSE;
+
 	err = VOP_BMAP(vp, reqblock, (struct vnode **) 0, &bn,
 		after, before);
 	if (err)
diff -ur src/usr.sbin/lpr/common_source/displayq.c 
src/usr.sbin/lpr/common_source/displayq.c
--- src/usr.sbin/lpr/common_source/displayq.c	Wed Oct 15 05:25:35 1997
+++ src/usr.sbin/lpr/common_source/displayq.c	Wed Dec 24 11:48:50 1997
@@ -242,6 +242,7 @@
 	savealrm = signal(SIGALRM, alarmhandler);
 	alarm(CT);
 	fd = getport(RM, 0);
+	alarm(0);
 	(void)signal(SIGALRM, savealrm);
 	if (fd < 0) {
 		if (from != host)
diff -ur src/usr.sbin/lpr/lpd/printjob.c src/usr.sbin/lpr/lpd/printjob.c
--- src/usr.sbin/lpr/lpd/printjob.c	Wed Oct 15 02:56:00 1997
+++ src/usr.sbin/lpr/lpd/printjob.c	Wed Dec 24 11:49:10 1997
@@ -1474,6 +1474,7 @@
 		savealrm = signal(SIGALRM, alarmhandler);
 		alarm(CT);
 		pfd = getport(cp, port);
+		alarm(0);
 		(void)signal(SIGALRM, savealrm);
 		if (pfd < 0 && errno == ECONNREFUSED)
 			resp = 1;
@@ -1541,6 +1542,7 @@
 		savealrm = signal(SIGALRM, alarmhandler);
 		alarm(CT);
 		pfd = getport(RM, 0);
+		alarm(0);
 		(void)signal(SIGALRM, savealrm);
 		if (pfd >= 0) {
 			(void) snprintf(line, sizeof(line), "\2%s\n", RP);



Regards,                       Phone:  (250)387-8437
Cy Schubert                      Fax:  (250)387-5766
UNIX Support                   OV/VM:  BCSC02(CSCHUBER)
ITSD                          BITNET:  CSCHUBER@BCSC02.BITNET
Government of BC            Internet:  cschuber@uumail.gov.bc.ca
                                       Cy.Schubert@gems8.gov.bc.ca




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199803231937.LAA14250>