lkml.org 
[lkml]   [1998]   [Jan]   [18]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
DateSun, 18 Jan 98 15:27 GMT
From(Alan Cox)
SubjectFirst snapshot of a proposed set of fixes to make 2.0.34
I'd appreciate feedback on these - especially on the Alpha platform so I can fix any further
problems they may have caused someone and submit this on to Linus for 2.0.34

o	sysctl oops
o	ptrace oops
o	signal oops
o	i_count exploit
o	autofw help text
o	LDT memory leak
o	Warning in cdrom.c
o	Warning in eth16i.c
o	Remove experimental tag fro DLCI/SDLA support
o	SMC ultra32 module fix
o	eql warning
o	new_tunnel warning
o	kerneld/ifconfig exploit
o	ignore source quench and drive by the dropped frames (current "good practice")

[Items marked "warning" indicate compiler warnings that turned out to be code that is 'wrong' from
 a perfect compiler correctness viewpoint but worked correctly before]

[Items marked "oops" fix non fatal Oops events]

[Items marked "exploit" fix something that allowed you to either crash the machine as any user
 or to get root]

--------------------------------------------------------------------------------------------------
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/Documentation/Configure.help linux/Documentation/Configure.help
--- linux.van2033/Documentation/Configure.help	Sun Jan 18 14:15:57 1998
+++ linux/Documentation/Configure.help	Sun Jan 18 14:26:43 1998
@@ -976,16 +976,13 @@
   IP always defragment.
   If you want this, say Y.
 
-IP: ipautofw masquerade support
-CONFIG_IP_MASQUERADE_IPAUTOFW (Experimental)
-  ipautofw is a program by Richard Lynch allowing additional
-  support for masquerading protocols which do not (as yet)
-  have additional protocol helpers.  
-  Information and source for ipautofw is available from
-  ftp://ftp.netis.com/pub/members/rlynch/
-  The ipautofw code is still under development and so is currently
-  marked EXPERIMENTAL.
-  If you want this, say Y.
+IP: ipautofw masquerading (EXPERIMENTAL)
+CONFIG_IP_MASQUERADE_IPAUTOFW
+
+  Richard Lynch's ipautofw allows masquerading to work with protocols
+  which do not (as yet) have specific protocol helpers.  Its source, and
+  other information, is available at
+  ftp://ftp.netis.com/pub/members/rlynch/. 
 
 IP: ICMP masquerading
 CONFIG_IP_MASQUERADE_ICMP
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- linux.van2033/arch/i386/kernel/process.c	Sun Jan 18 14:15:47 1998
+++ linux/arch/i386/kernel/process.c	Sun Jan 18 14:21:45 1998
@@ -421,8 +421,9 @@
 	int i;
 
 	if (current->ldt) {
-		free_page((unsigned long) current->ldt);
+		void * ldt = current->ldt;
 		current->ldt = NULL;
+		vfree(ldt);
 		for (i=1 ; i<NR_TASKS ; i++) {
 			if (task[i] == current)  {
 				set_ldt_desc(gdt+(i<<1)+
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
--- linux.van2033/arch/i386/kernel/ptrace.c	Sun Jan 18 14:15:47 1998
+++ linux/arch/i386/kernel/ptrace.c	Sun Jan 18 14:20:09 1998
@@ -416,6 +416,60 @@
 	return tmp;
 }
 
+void safe_wake_up_process(struct task_struct * p)
+{
+	struct desc_struct * d;
+	unsigned long limit;
+
+	void check(int index, int mask, int value) {
+		unsigned long selector, limit;
+
+		if (!p) return;
+
+		selector = get_stack_long(p, sizeof(long)*index - MAGICNUMBER);
+		if (selector & 4) {
+			d = p->ldt;
+			if (d) limit = get_limit(p->tss.ldt); else limit = 0;
+		} else {
+			d = gdt;
+			limit = 8 * 8;
+		}
+
+		if ((selector & 0xFFF8) >= limit) {
+			d = NULL;
+			force_sig(SIGSEGV, p); p = NULL;
+		} else {
+			d += selector >> 3;
+			if ((d->b & mask) != value ||
+			    (d->b >> 13) < (selector & 3)) {
+				force_sig(SIGSEGV, p); p = NULL;
+			}
+		}
+	}
+
+	check(DS, 0x9800, 0x9000); /* Allow present data segments only */
+	check(ES, 0x9800, 0x9000);
+	check(FS, 0x9800, 0x9000);
+	check(GS, 0x9800, 0x9000);
+	check(SS, 0x9A00, 0x9200); /* Stack segment should not be read-only */
+	check(CS, 0x9800, 0x9800); /* Allow present code segments only */
+
+	if (!p) return;
+
+	if (d) {
+		limit = (d->a & 0xFFFF) | (d->b & 0xF0000);
+		if (d->b & 0x800000) {
+			limit <<= 12; limit |= 0xFFF;
+		}
+
+		if (get_stack_long(p, sizeof(long)*EIP - MAGICNUMBER) > limit) {
+			force_sig(SIGSEGV, p); return;
+		}
+	}
+
+	wake_up_process(p);
+}
+
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
 {
 	struct task_struct *child;
@@ -609,7 +663,7 @@
 			else
 				child->flags &= ~PF_TRACESYS;
 			child->exit_code = data;
-			wake_up_process(child);
+			safe_wake_up_process(child);
 	/* make sure the single step bit is not set. */
 			tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG;
 			put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
@@ -642,8 +696,8 @@
 			child->flags &= ~PF_TRACESYS;
 			tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG;
 			put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp);
-			wake_up_process(child);
 			child->exit_code = data;
+			safe_wake_up_process(child);
 	/* give it a chance to run. */
 			return 0;
 		}
@@ -654,8 +708,8 @@
 			if ((unsigned long) data > NSIG)
 				return -EIO;
 			child->flags &= ~(PF_PTRACED|PF_TRACESYS);
-			wake_up_process(child);
 			child->exit_code = data;
+			safe_wake_up_process(child);
 			REMOVE_LINKS(child);
 			child->p_pptr = child->p_opptr;
 			SET_LINKS(child);
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
--- linux.van2033/arch/i386/kernel/signal.c	Sun Jan 18 14:14:04 1998
+++ linux/arch/i386/kernel/signal.c	Sun Jan 18 14:20:09 1998
@@ -15,6 +15,7 @@
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 
+#include <asm/system.h>
 #include <asm/segment.h>
 
 #define _S(nr) (1<<((nr)-1))
@@ -80,13 +81,40 @@
 asmlinkage int sys_sigreturn(unsigned long __unused)
 {
 #define COPY(x) regs->x = context.x
+#define CHECK_DATA(x, mask, value) \
+__asm__("larw %0,%%ax\n\t" \
+	"jnz asm_badframe\n\t" \
+	"andl $" mask ",%%eax\n\t" \
+	"cmpl $" value ",%%eax\n\t" \
+	"jne asm_badframe" \
+	: \
+	: "g" (context.x) \
+	: "ax", "cc");
+#define CHECK_CODE(x, y) \
+__asm__("larw %0,%%ax\n\t" \
+	"jnz asm_badframe\n\t" \
+	"andl $0x9800,%%eax\n\t" \
+	"cmpl $0x9800,%%eax\n\t" /* Allow present code segments only */ \
+	"jne asm_badframe\n\t" \
+	"lsll %0,%%eax\n\t" \
+	"cmp %1,%%eax\n\t" /* Check context.eip against the segment limit */ \
+	"jb asm_badframe" \
+	: \
+	: "g" (context.x), "g" (context.y) \
+	: "ax", "cc");
 #define COPY_SEG(x) \
+CHECK_DATA(x, "0x9800", "0x9000") /* Allow present data segments only */ \
 if (   (context.x & 0xfffc)     /* not a NULL selectors */ \
     && (context.x & 0x4) != 0x4 /* not a LDT selector */ \
     && (context.x & 3) != 3     /* not a RPL3 GDT selector */ \
    ) goto badframe; COPY(x);
-#define COPY_SEG_STRICT(x) \
+#define COPY_STACK(x) \
+CHECK_DATA(x, "0x9A00", "0x9200") /* Stack segment should not be read-only */ \
 if (!(context.x & 0xfffc) || (context.x & 3) != 3) goto badframe; COPY(x);
+#define COPY_CODE(x, y) \
+CHECK_CODE(x, y) \
+if (!(context.x & 0xfffc) || (context.x & 3) != 3) goto badframe; \
+COPY(x); COPY(y);
 	struct sigcontext_struct context;
 	struct pt_regs * regs;
 
@@ -99,9 +127,8 @@
 	COPY_SEG(es);
 	COPY_SEG(fs);
 	COPY_SEG(gs);
-	COPY_SEG_STRICT(ss);
-	COPY_SEG_STRICT(cs);
-	COPY(eip);
+	COPY_STACK(ss);
+	COPY_CODE(cs, eip);
 	COPY(ecx); COPY(edx);
 	COPY(ebx);
 	COPY(esp); COPY(ebp);
@@ -117,6 +144,11 @@
 	}
 	return context.eax;
 badframe:
+	do_exit(SIGSEGV);
+}
+
+void asm_badframe(void)
+{
 	do_exit(SIGSEGV);
 }
 
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/block/md.c linux/drivers/block/md.c
--- linux.van2033/drivers/block/md.c	Sat Jun 29 22:04:00 1996
+++ linux/drivers/block/md.c	Sun Jan 18 14:42:10 1998
@@ -202,7 +202,7 @@
   
   if (inode->i_count>1 || md_dev[minor].busy>1) /* ioctl : one open channel */
   {
-    printk ("STOP_MD md%x failed : i_count=%d, busy=%d\n", minor, inode->i_count, md_dev[minor].busy);
+    printk ("STOP_MD md%x failed : i_count=%ld, busy=%d\n", minor, inode->i_count, md_dev[minor].busy);
     return -EBUSY;
   }
   
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- linux.van2033/drivers/cdrom/cdrom.c	Sat Aug 17 19:19:26 1996
+++ linux/drivers/cdrom/cdrom.c	Sun Jan 18 15:40:29 1998
@@ -97,7 +97,9 @@
 
 /* We need our own cdrom error types! This is a temporary solution. */
 
+#ifndef ENOMEDIUM
 #define ENOMEDIUM EAGAIN				/* no medium in removable device */
+#endif
 
 /* We use the open-option O_NONBLOCK to indicate that the
  * purpose of opening is only for subsequent ioctl() calls; no device
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/Config.in linux/drivers/net/Config.in
--- linux.van2033/drivers/net/Config.in	Sun Jan 18 14:14:19 1998
+++ linux/drivers/net/Config.in	Sun Jan 18 14:21:07 1998
@@ -3,13 +3,11 @@
 #
 tristate 'Dummy net driver support' CONFIG_DUMMY
 tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'Frame relay DLCI support (EXPERIMENTAL)' CONFIG_DLCI
-  if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then
-    int '  Max open DLCI' CONFIG_DLCI_COUNT 24
-    int '  Max DLCI per device' CONFIG_DLCI_MAX 8
-    dep_tristate '  SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI
-  fi
+tristate 'Frame relay DLCI support' CONFIG_DLCI
+if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then
+  int '  Max open DLCI' CONFIG_DLCI_COUNT 24
+  int '  Max DLCI per device' CONFIG_DLCI_MAX 8
+  dep_tristate '  SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI
 fi
 tristate 'PLIP (parallel port) support' CONFIG_PLIP
 tristate 'PPP (point-to-point) support' CONFIG_PPP
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/Makefile linux/drivers/net/Makefile
--- linux.van2033/drivers/net/Makefile	Sun Jan 18 14:14:19 1998
+++ linux/drivers/net/Makefile	Sun Jan 18 14:18:32 1998
@@ -148,7 +148,7 @@
 L_OBJS += smc-ultra32.o
 CONFIG_8390_BUILTIN = y
 else
-  ifeq ($(CONFIG_ULTRA),m)
+  ifeq ($(CONFIG_ULTRA32),m)
   CONFIG_8390_MODULE = y
   M_OBJS += smc-ultra32.o
   endif
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/eql.c linux/drivers/net/eql.c
--- linux.van2033/drivers/net/eql.c	Sun Jan 18 14:14:21 1998
+++ linux/drivers/net/eql.c	Sun Jan 18 15:39:36 1998
@@ -375,7 +375,6 @@
 	equalizer_t *eql = (equalizer_t *) dev->priv;
 	struct device *slave_dev = 0;
 	slave_t *slave;
-	struct sk_buff *skb2;
 
 	if (skb == NULL)
 		return 0;
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/eth16i.c linux/drivers/net/eth16i.c
--- linux.van2033/drivers/net/eth16i.c	Sun Jan 18 14:14:21 1998
+++ linux/drivers/net/eth16i.c	Sun Jan 18 15:43:38 1998
@@ -332,7 +332,7 @@
 static int eth16i_tx(struct sk_buff *skb, struct device *dev);
 static void eth16i_rx(struct device *dev);
 static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs); 
+static void eth16i_multicast(struct device *dev); 
 static void eth16i_select_regbank(unsigned char regbank, short ioaddr);
 static void eth16i_initialize(struct device *dev);
 static struct enet_statistics *eth16i_get_stats(struct device *dev);
@@ -1152,7 +1152,7 @@
   return;
 }
 
-static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs)
+static void eth16i_multicast(struct device *dev)
 {
   short ioaddr = dev->base_addr;
   
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/new_tunnel.c linux/drivers/net/new_tunnel.c
--- linux.van2033/drivers/net/new_tunnel.c	Sun Jan 18 14:14:23 1998
+++ linux/drivers/net/new_tunnel.c	Sun Jan 18 15:38:25 1998
@@ -267,7 +267,7 @@
 
 		/* Tack on our header */
 		new_skb->h.iph = (struct iphdr *) skb_push(new_skb, tunnel_hlen);
-		new_skb->mac.raw = new_skb->ip_hdr;
+		new_skb->mac.raw = (void *)new_skb->ip_hdr;
 
 		/* Free the old packet, we no longer need it */
 		dev_kfree_skb(skb, FREE_WRITE);
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/ext/freelists.c linux/fs/ext/freelists.c
--- linux.van2033/fs/ext/freelists.c	Sat Nov 30 10:21:19 1996
+++ linux/fs/ext/freelists.c	Sun Jan 18 15:41:13 1998
@@ -188,7 +188,7 @@
 		return;
 	}
 	if (inode->i_count != 1) {
-		printk("free_inode: inode has count=%d\n",inode->i_count);
+		printk("free_inode: inode has count=%ld\n",inode->i_count);
 		return;
 	}
 	if (inode->i_nlink) {
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/ext2/ialloc.c linux/fs/ext2/ialloc.c
--- linux.van2033/fs/ext2/ialloc.c	Sun Jan 18 14:14:37 1998
+++ linux/fs/ext2/ialloc.c	Sun Jan 18 14:58:24 1998
@@ -196,7 +196,7 @@
 		return;
 	}
 	if (inode->i_count > 1) {
-		printk ("ext2_free_inode: inode has count=%d\n",
+		printk ("ext2_free_inode: inode has count=%ld\n",
 			inode->i_count);
 		return;
 	}
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/minix/bitmap.c linux/fs/minix/bitmap.c
--- linux.van2033/fs/minix/bitmap.c	Sat Nov 30 10:21:20 1996
+++ linux/fs/minix/bitmap.c	Sun Jan 18 15:40:51 1998
@@ -187,7 +187,7 @@
 		return;
 	}
 	if (inode->i_count != 1) {
-		printk("free_inode: inode has count=%d\n",inode->i_count);
+		printk("free_inode: inode has count=%ld\n",inode->i_count);
 		return;
 	}
 	if (inode->i_nlink) {
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- linux.van2033/fs/ncpfs/inode.c	Sun Jan 18 14:14:39 1998
+++ linux/fs/ncpfs/inode.c	Sun Jan 18 15:42:03 1998
@@ -145,7 +145,7 @@
 	lock_super(sb);
 
 	if (inode->i_count > 1) {
-printk("ncp_put_inode: inode in use device %s, inode %ld, count=%d\n", 
+printk("ncp_put_inode: inode in use device %s, inode %ld, count=%ld\n", 
 kdevname(inode->i_dev), inode->i_ino, inode->i_count);
 		goto unlock;
 	}
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- linux.van2033/fs/smbfs/inode.c	Sun Jan 18 14:14:39 1998
+++ linux/fs/smbfs/inode.c	Sun Jan 18 15:41:51 1998
@@ -99,7 +99,7 @@
 	__u32 mtime = inode->i_mtime;
 
 	if (inode->i_count > 1) {
-		printk("smb_put_inode: in use device %s, inode %ld count=%d\n",
+		printk("smb_put_inode: in use device %s, inode %ld count=%ld\n",
 			kdevname(inode->i_dev), inode->i_ino, inode->i_count);
 		return;
 	}
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/sysv/ialloc.c linux/fs/sysv/ialloc.c
--- linux.van2033/fs/sysv/ialloc.c	Sat Nov 30 10:21:21 1996
+++ linux/fs/sysv/ialloc.c	Sun Jan 18 15:41:35 1998
@@ -63,7 +63,7 @@
 		return;
 	}
 	if (inode->i_count != 1) {
-		printk("sysv_free_inode: inode has count=%d\n", inode->i_count);
+		printk("sysv_free_inode: inode has count=%ld\n", inode->i_count);
 		return;
 	}
 	if (inode->i_nlink) {
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/ufs/ufs_inode.c linux/fs/ufs/ufs_inode.c
--- linux.van2033/fs/ufs/ufs_inode.c	Sat Nov 30 10:21:22 1996
+++ linux/fs/ufs/ufs_inode.c	Sun Jan 18 15:42:20 1998
@@ -23,7 +23,7 @@
 
 void ufs_print_inode(struct inode * inode)
 {
-	printk("ino %lu  mode 0%6.6o  lk %d  uid %d  gid %d  sz %lu  blks %lu  cnt %u\n",
+	printk("ino %lu  mode 0%6.6o  lk %d  uid %d  gid %d  sz %lu  blks %lu  cnt %lu\n",
 	       inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid, inode->i_gid, inode->i_size, inode->i_blocks, inode->i_count);
 	printk("  db <0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x>\n",
 	       inode->u.ufs_i.ui_db[0], inode->u.ufs_i.ui_db[1],
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/include/linux/fs.h linux/include/linux/fs.h
--- linux.van2033/include/linux/fs.h	Sun Jan 18 14:15:52 1998
+++ linux/include/linux/fs.h	Sun Jan 18 14:40:25 1998
@@ -304,7 +304,7 @@
 	struct inode *i_hash_next, *i_hash_prev;
 	struct inode *i_bound_to, *i_bound_by;
 	struct inode *i_mount;
-	unsigned short i_count;
+	unsigned long i_count;	/* needs to be > (address_space * tasks)>>pagebits */
 	unsigned short i_flags;
 	unsigned char i_lock;
 	unsigned char i_dirt;
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/kernel/sysctl.c linux/kernel/sysctl.c
--- linux.van2033/kernel/sysctl.c	Sun Jan 18 14:14:45 1998
+++ linux/kernel/sysctl.c	Sun Jan 18 14:20:09 1998
@@ -180,7 +180,7 @@
 	struct ctl_table_header *tmp;
 	void *context;
 	
-	if (nlen == 0 || nlen >= CTL_MAXNAME)
+	if (nlen <= 0 || nlen >= CTL_MAXNAME)
 		return -ENOTDIR;
 	
 	error = verify_area(VERIFY_READ,name,nlen*sizeof(int));
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/net/core/dev.c linux/net/core/dev.c
--- linux.van2033/net/core/dev.c	Sun Jan 18 14:14:47 1998
+++ linux/net/core/dev.c	Sun Jan 18 14:23:47 1998
@@ -225,7 +225,7 @@
 
 extern __inline__ void dev_load(const char *name)
 {
-	if(!dev_get(name)) {
+	if(!dev_get(name) && suser()) {
 #ifdef CONFIG_NET_ALIAS
 		const char *sptr;
  
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/net/ipv4/Config.in linux/net/ipv4/Config.in
--- linux.van2033/net/ipv4/Config.in	Sun Jan 18 14:14:47 1998
+++ linux/net/ipv4/Config.in	Sun Jan 18 14:26:43 1998
@@ -15,7 +15,7 @@
       if [ "$CONFIG_IP_MASQUERADE" != "n" ]; then
         comment 'Protocol-specific masquerading support will be built as modules.'
         if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then	
-          bool 'IP: ipautofw masq support' CONFIG_IP_MASQUERADE_IPAUTOFW
+          bool 'IP: ipautofw masquerading (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_IPAUTOFW
         fi
         bool 'IP: ICMP masquerading' CONFIG_IP_MASQUERADE_ICMP
       fi
diff --unified --new-file --recursive --exclude-from exclude linux.van2033/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- linux.van2033/net/ipv4/tcp.c	Sun Jan 18 14:14:49 1998
+++ linux/net/ipv4/tcp.c	Sun Jan 18 15:05:48 1998
@@ -740,16 +740,8 @@
 
 	if (type == ICMP_SOURCE_QUENCH)
 	{
-		/*
-		 * FIXME:
-		 * Follow BSD for now and just reduce cong_window to 1 again.
-		 * It is possible that we just want to reduce the
-		 * window by 1/2, or that we want to reduce ssthresh by 1/2
-		 * here as well.
-		 */
-		sk->cong_window = 1;
-		sk->cong_count = 0;
-		sk->high_seq = sk->sent_seq;
+		/* Current practice says these frames are bad, plus the drops
+		   will account right anyway. If we act on this we stall doubly */
 		return;
 	}
 
\
 
 \ /
  Last update: 2005-03-22 12:41    [from the cache]
©2003-2008