r2574 - in trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian: . patches patches/series

Joshua Kwan joshk@costa.debian.org
Sun, 27 Feb 2005 06:06:48 +0100


Author: joshk
Date: 2005-02-27 06:06:47 +0100 (Sun, 27 Feb 2005)
New Revision: 2574

Added:
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-1.dpatch
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-2.dpatch
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-3.dpatch
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-4.dpatch
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/setsid-race.dpatch
Modified:
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-14
   trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-9
Log:
UNTESTED ipv4-fragment-queues-*.dpatches that work. Will test on i386 soon, and have dilinger give them a look

Modified: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog	2005-02-26 12:20:34 UTC (rev 2573)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/changelog	2005-02-27 05:06:47 UTC (rev 2574)
@@ -49,11 +49,15 @@
     to a denial of service. (Joshua Kwan)
 
   * outs.dpatch: [CAN-2005-0204] AMD64, allows local users to write to
-    privileged IO ports via OUTS instruction. 
+    privileged IO ports via OUTS instruction.
     (Simon Horman) (closes: #296700)
 
- -- Simon Horman <horms@debian.org>  Thu, 24 Feb 2005 18:57:06 +0900
+  * ipv4-fragment-queues.dpatch, ipv4-fragment-queues-2.dpatch:
+    fix potential information leak by making fragment queues private.
+    (Joshua Kwan, Simon Horman)            
 
+ -- Joshua Kwan <joshk@triplehelix.org>  Sat, 26 Feb 2005 21:01:07 -0800
+
 kernel-source-2.6.8 (2.6.8-13) unstable; urgency=high
 
   * add more USB card reader blacklist entries.  Patch from Fedora via

Added: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-1.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-1.dpatch	2005-02-26 12:20:34 UTC (rev 2573)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-1.dpatch	2005-02-27 05:06:47 UTC (rev 2574)
@@ -0,0 +1,150 @@
+# origin: bk
+# key: 4123c9e5boprDssFy_GeUZ-yvUntiw (linux-2.5)
+# description: 
+# inclusion: 
+# revision date: 2005-02-26
+
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+#   2004/08/18 14:28:05-07:00 davem@nuts.davemloft.net 
+#   [IPV4]: Fix theoretical loop on SMP in ip_evictor().
+#   
+#   Snapshot the amount of work to do, and just do it.
+#   In this way we avoid a theoretical loop whereby
+#   one cpu sits in ip_evictor() tossing fragments
+#   while another keeps adding a fragment just as we
+#   bring ip_frag_mem  down below the low threshold.
+#   
+#   Signed-off-by: David S. Miller <davem@redhat.com>
+# 
+# net/ipv4/ip_fragment.c
+#   2004/08/18 14:27:32-07:00 davem@nuts.davemloft.net +22 -15
+#   [IPV4]: Fix theoretical loop on SMP in ip_evictor().
+#   
+#   Snapshot the amount of work to do, and just do it.
+#   In this way we avoid a theoretical loop whereby
+#   one cpu sits in ip_evictor() tossing fragments
+#   while another keeps adding a fragment just as we
+#   bring ip_frag_mem  down below the low threshold.
+#   
+#   Signed-off-by: David S. Miller <davem@redhat.com>
+# 
+diff -Nru a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
+--- a/net/ipv4/ip_fragment.c	2005-02-26 20:57:09 -08:00
++++ b/net/ipv4/ip_fragment.c	2005-02-26 20:57:09 -08:00
+@@ -169,14 +169,18 @@
+ atomic_t ip_frag_mem = ATOMIC_INIT(0);	/* Memory used for fragments */
+ 
+ /* Memory Tracking Functions. */
+-static __inline__ void frag_kfree_skb(struct sk_buff *skb)
++static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
+ {
++	if (work)
++		*work -= skb->truesize;
+ 	atomic_sub(skb->truesize, &ip_frag_mem);
+ 	kfree_skb(skb);
+ }
+ 
+-static __inline__ void frag_free_queue(struct ipq *qp)
++static __inline__ void frag_free_queue(struct ipq *qp, int *work)
+ {
++	if (work)
++		*work -= sizeof(struct ipq);
+ 	atomic_sub(sizeof(struct ipq), &ip_frag_mem);
+ 	kfree(qp);
+ }
+@@ -195,7 +199,7 @@
+ /* Destruction primitives. */
+ 
+ /* Complete destruction of ipq. */
+-static void ip_frag_destroy(struct ipq *qp)
++static void ip_frag_destroy(struct ipq *qp, int *work)
+ {
+ 	struct sk_buff *fp;
+ 
+@@ -207,18 +211,18 @@
+ 	while (fp) {
+ 		struct sk_buff *xp = fp->next;
+ 
+-		frag_kfree_skb(fp);
++		frag_kfree_skb(fp, work);
+ 		fp = xp;
+ 	}
+ 
+ 	/* Finally, release the queue descriptor itself. */
+-	frag_free_queue(qp);
++	frag_free_queue(qp, work);
+ }
+ 
+-static __inline__ void ipq_put(struct ipq *ipq)
++static __inline__ void ipq_put(struct ipq *ipq, int *work)
+ {
+ 	if (atomic_dec_and_test(&ipq->refcnt))
+-		ip_frag_destroy(ipq);
++		ip_frag_destroy(ipq, work);
+ }
+ 
+ /* Kill ipq entry. It is not destroyed immediately,
+@@ -243,10 +247,13 @@
+ {
+ 	struct ipq *qp;
+ 	struct list_head *tmp;
++	int work;
+ 
+-	for(;;) {
+-		if (atomic_read(&ip_frag_mem) <= sysctl_ipfrag_low_thresh)
+-			return;
++	work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh;
++	if (work <= 0)
++		return;
++
++	while (work > 0) {
+ 		read_lock(&ipfrag_lock);
+ 		if (list_empty(&ipq_lru_list)) {
+ 			read_unlock(&ipfrag_lock);
+@@ -262,7 +269,7 @@
+ 			ipq_kill(qp);
+ 		spin_unlock(&qp->lock);
+ 
+-		ipq_put(qp);
++		ipq_put(qp, &work);
+ 		IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
+ 	}
+ }
+@@ -294,7 +301,7 @@
+ 	}
+ out:
+ 	spin_unlock(&qp->lock);
+-	ipq_put(qp);
++	ipq_put(qp, NULL);
+ }
+ 
+ /* Creation primitives. */
+@@ -317,7 +324,7 @@
+ 			atomic_inc(&qp->refcnt);
+ 			write_unlock(&ipfrag_lock);
+ 			qp_in->last_in |= COMPLETE;
+-			ipq_put(qp_in);
++			ipq_put(qp_in, NULL);
+ 			return qp;
+ 		}
+ 	}
+@@ -506,7 +513,7 @@
+ 				qp->fragments = next;
+ 
+ 			qp->meat -= free_it->len;
+-			frag_kfree_skb(free_it);
++			frag_kfree_skb(free_it, NULL);
+ 		}
+ 	}
+ 
+@@ -657,7 +664,7 @@
+ 			ret = ip_frag_reasm(qp, dev);
+ 
+ 		spin_unlock(&qp->lock);
+-		ipq_put(qp);
++		ipq_put(qp, NULL);
+ 		return ret;
+ 	}
+ 

Added: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-2.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-2.dpatch	2005-02-26 12:20:34 UTC (rev 2573)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-2.dpatch	2005-02-27 05:06:47 UTC (rev 2574)
@@ -0,0 +1,176 @@
+# origin: bk
+# key: 4132a8b3rjfwez42jjKzag5rrzugpA (linux-2.5)
+# description: 
+# inclusion: 
+# revision date: 2005-02-26
+
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+#   2004/08/29 21:10:27-07:00 kaber@trash.net 
+#   [NETFILTER]: Flush fragment queue on conntrack unload
+#   
+#   Problem discovered, and original version of patch, by
+#   Olaf Kirch.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@redhat.com>
+# 
+# include/linux/netfilter_ipv4/ip_conntrack.h
+#   2004/08/29 21:10:09-07:00 kaber@trash.net +1 -0
+#   [NETFILTER]: Flush fragment queue on conntrack unload
+#   
+#   Problem discovered, and original version of patch, by
+#   Olaf Kirch.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@redhat.com>
+# 
+# include/net/ip.h
+#   2004/08/29 21:10:09-07:00 kaber@trash.net +1 -0
+#   [NETFILTER]: Flush fragment queue on conntrack unload
+#   
+#   Problem discovered, and original version of patch, by
+#   Olaf Kirch.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@redhat.com>
+# 
+# net/ipv4/ip_fragment.c
+#   2004/08/29 21:10:09-07:00 kaber@trash.net +14 -3
+#   [NETFILTER]: Flush fragment queue on conntrack unload
+#   
+#   Problem discovered, and original version of patch, by
+#   Olaf Kirch.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@redhat.com>
+# 
+# net/ipv4/netfilter/ip_conntrack_core.c
+#   2004/08/29 21:10:09-07:00 kaber@trash.net +8 -0
+#   [NETFILTER]: Flush fragment queue on conntrack unload
+#   
+#   Problem discovered, and original version of patch, by
+#   Olaf Kirch.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@redhat.com>
+# 
+# net/ipv4/netfilter/ip_conntrack_standalone.c
+#   2004/08/29 21:10:09-07:00 kaber@trash.net +6 -0
+#   [NETFILTER]: Flush fragment queue on conntrack unload
+#   
+#   Problem discovered, and original version of patch, by
+#   Olaf Kirch.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@redhat.com>
+# 
+diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
+--- a/include/linux/netfilter_ipv4/ip_conntrack.h	2005-02-26 20:56:17 -08:00
++++ b/include/linux/netfilter_ipv4/ip_conntrack.h	2005-02-26 20:56:17 -08:00
+@@ -275,6 +275,7 @@
+ /* Fake conntrack entry for untracked connections */
+ extern struct ip_conntrack ip_conntrack_untracked;
+ 
++extern int ip_ct_no_defrag;
+ /* Returns new sk_buff, or NULL */
+ struct sk_buff *
+ ip_ct_gather_frags(struct sk_buff *skb);
+diff -Nru a/include/net/ip.h b/include/net/ip.h
+--- a/include/net/ip.h	2005-02-26 20:56:17 -08:00
++++ b/include/net/ip.h	2005-02-26 20:56:17 -08:00
+@@ -255,6 +255,7 @@
+  */
+  
+ struct sk_buff *ip_defrag(struct sk_buff *skb);
++extern void ipfrag_flush(void);
+ extern int ip_frag_nqueues;
+ extern atomic_t ip_frag_mem;
+ 
+diff -Nru a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
+--- a/net/ipv4/ip_fragment.c	2005-02-26 20:56:17 -08:00
++++ b/net/ipv4/ip_fragment.c	2005-02-26 20:56:17 -08:00
+@@ -241,15 +241,15 @@
+ }
+ 
+ /* Memory limiting on fragments.  Evictor trashes the oldest 
+- * fragment queue until we are back under the low threshold.
++ * fragment queue until we are back under the threshold.
+  */
+-static void ip_evictor(void)
++static void __ip_evictor(int threshold)
+ {
+ 	struct ipq *qp;
+ 	struct list_head *tmp;
+ 	int work;
+ 
+-	work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh;
++	work = atomic_read(&ip_frag_mem) - threshold;
+ 	if (work <= 0)
+ 		return;
+ 
+@@ -274,6 +274,11 @@
+ 	}
+ }
+ 
++static inline void ip_evictor(void)
++{
++	__ip_evictor(sysctl_ipfrag_low_thresh);
++}
++
+ /*
+  * Oops, a fragment queue timed out.  Kill it and send an ICMP reply.
+  */
+@@ -684,4 +689,10 @@
+ 	add_timer(&ipfrag_secret_timer);
+ }
+ 
++void ipfrag_flush(void)
++{
++	__ip_evictor(0);
++}
++
+ EXPORT_SYMBOL(ip_defrag);
++EXPORT_SYMBOL(ipfrag_flush);
+diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
+--- a/net/ipv4/netfilter/ip_conntrack_core.c	2005-02-26 20:56:17 -08:00
++++ b/net/ipv4/netfilter/ip_conntrack_core.c	2005-02-26 20:56:17 -08:00
+@@ -1173,6 +1173,8 @@
+ 	}
+ }
+ 
++int ip_ct_no_defrag;
++
+ /* Returns new sk_buff, or NULL */
+ struct sk_buff *
+ ip_ct_gather_frags(struct sk_buff *skb)
+@@ -1181,6 +1183,12 @@
+ #ifdef CONFIG_NETFILTER_DEBUG
+ 	unsigned int olddebug = skb->nf_debug;
+ #endif
++
++	if (unlikely(ip_ct_no_defrag)) {
++		kfree_skb(skb);
++		return NULL;
++	}
++
+ 	if (sk) {
+ 		sock_hold(sk);
+ 		skb_orphan(skb);
+diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
+--- a/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-02-26 20:56:17 -08:00
++++ b/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-02-26 20:56:17 -08:00
+@@ -805,6 +805,12 @@
+  cleanup_defraglocalops:
+ 	nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
+  cleanup_defragops:
++	/* Frag queues may hold fragments with skb->dst == NULL */
++	ip_ct_no_defrag = 1;
++	smp_wmb();
++	local_bh_disable();
++	ipfrag_flush();
++	local_bh_enable();
+ 	nf_unregister_hook(&ip_conntrack_defrag_ops);
+  cleanup_proc_stat:
+ 	proc_net_remove("ip_conntrack_stat");

Added: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-3.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-3.dpatch	2005-02-26 12:20:34 UTC (rev 2573)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-3.dpatch	2005-02-27 05:06:47 UTC (rev 2574)
@@ -0,0 +1,404 @@
+# origin: bk
+# key: 41f8843a8ZMCNuP3meYAYnnXd3CO_g (linux-2.5)
+# description: global availability of fragment queues allows information leak
+# inclusion: 2.6.11?
+# revision date: 2005-02-18
+
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+#   2005/01/26 22:03:38-08:00 kaber@trash.net 
+#   [IPV4]: Keep fragment queues private to each user.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@davemloft.net>
+# 
+# include/linux/netfilter_ipv4/ip_conntrack.h
+#   2005/01/26 22:03:17-08:00 kaber@trash.net +1 -2
+#   [IPV4]: Keep fragment queues private to each user.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@davemloft.net>
+# 
+# include/net/ip.h
+#   2005/01/26 22:03:17-08:00 kaber@trash.net +14 -3
+#   [IPV4]: Keep fragment queues private to each user.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@davemloft.net>
+# 
+# net/ipv4/ip_fragment.c
+#   2005/01/26 22:03:17-08:00 kaber@trash.net +13 -20
+#   [IPV4]: Keep fragment queues private to each user.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@davemloft.net>
+# 
+# net/ipv4/ip_input.c
+#   2005/01/26 22:03:17-08:00 kaber@trash.net +2 -2
+#   [IPV4]: Keep fragment queues private to each user.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@davemloft.net>
+# 
+# net/ipv4/ipvs/ip_vs_core.c
+#   2005/01/26 22:03:17-08:00 kaber@trash.net +11 -8
+#   [IPV4]: Keep fragment queues private to each user.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@davemloft.net>
+# 
+# net/ipv4/netfilter/ip_conntrack_core.c
+#   2005/01/26 22:03:17-08:00 kaber@trash.net +2 -9
+#   [IPV4]: Keep fragment queues private to each user.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@davemloft.net>
+# 
+# net/ipv4/netfilter/ip_conntrack_standalone.c
+#   2005/01/26 22:03:17-08:00 kaber@trash.net +4 -7
+#   [IPV4]: Keep fragment queues private to each user.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@davemloft.net>
+# 
+# net/ipv4/netfilter/ip_nat_standalone.c
+#   2005/01/26 22:03:17-08:00 kaber@trash.net +1 -1
+#   [IPV4]: Keep fragment queues private to each user.
+#   
+#   Signed-off-by: Patrick McHardy <kaber@trash.net>
+#   Signed-off-by: David S. Miller <davem@davemloft.net>
+# 
+diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
+--- a/include/linux/netfilter_ipv4/ip_conntrack.h	2005-02-18 18:05:57 -08:00
++++ b/include/linux/netfilter_ipv4/ip_conntrack.h	2005-02-18 18:05:57 -08:00
+@@ -262,10 +262,9 @@
+ /* Fake conntrack entry for untracked connections */
+ extern struct ip_conntrack ip_conntrack_untracked;
+ 
+-extern int ip_ct_no_defrag;
+ /* Returns new sk_buff, or NULL */
+ struct sk_buff *
+-ip_ct_gather_frags(struct sk_buff *skb);
++ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user);
+ 
+ /* Iterate over all conntracks: if iter returns true, it's deleted. */
+ extern void
+diff -Nru a/include/net/ip.h b/include/net/ip.h
+--- a/include/net/ip.h	2005-02-18 18:05:57 -08:00
++++ b/include/net/ip.h	2005-02-18 18:05:57 -08:00
+@@ -286,9 +286,20 @@
+ /*
+  *	Functions provided by ip_fragment.o
+  */
+- 
+-struct sk_buff *ip_defrag(struct sk_buff *skb);
+-extern void ipfrag_flush(void);
++
++enum ip_defrag_users
++{
++	IP_DEFRAG_LOCAL_DELIVER,
++	IP_DEFRAG_CALL_RA_CHAIN,
++	IP_DEFRAG_CONNTRACK_IN,
++	IP_DEFRAG_CONNTRACK_OUT,
++	IP_DEFRAG_NAT_OUT,
++	IP_DEFRAG_VS_IN,
++	IP_DEFRAG_VS_OUT,
++	IP_DEFRAG_VS_FWD
++};
++
++struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user);
+ extern int ip_frag_nqueues;
+ extern atomic_t ip_frag_mem;
+ 
+diff -Nru a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
+--- a/net/ipv4/ip_fragment.c	2005-02-18 18:05:57 -08:00
++++ b/net/ipv4/ip_fragment.c	2005-02-18 18:05:57 -08:00
+@@ -73,6 +73,7 @@
+ struct ipq {
+ 	struct ipq	*next;		/* linked list pointers			*/
+ 	struct list_head lru_list;	/* lru list member 			*/
++	u32		user;
+ 	u32		saddr;
+ 	u32		daddr;
+ 	u16		id;
+@@ -243,13 +244,13 @@
+ /* Memory limiting on fragments.  Evictor trashes the oldest 
+  * fragment queue until we are back under the threshold.
+  */
+-static void __ip_evictor(int threshold)
++static void ip_evictor(void)
+ {
+ 	struct ipq *qp;
+ 	struct list_head *tmp;
+ 	int work;
+ 
+-	work = atomic_read(&ip_frag_mem) - threshold;
++	work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh;
+ 	if (work <= 0)
+ 		return;
+ 
+@@ -274,11 +275,6 @@
+ 	}
+ }
+ 
+-static inline void ip_evictor(void)
+-{
+-	__ip_evictor(sysctl_ipfrag_low_thresh);
+-}
+-
+ /*
+  * Oops, a fragment queue timed out.  Kill it and send an ICMP reply.
+  */
+@@ -325,7 +321,8 @@
+ 		if(qp->id == qp_in->id		&&
+ 		   qp->saddr == qp_in->saddr	&&
+ 		   qp->daddr == qp_in->daddr	&&
+-		   qp->protocol == qp_in->protocol) {
++		   qp->protocol == qp_in->protocol &&
++		   qp->user == qp_in->user) {
+ 			atomic_inc(&qp->refcnt);
+ 			write_unlock(&ipfrag_lock);
+ 			qp_in->last_in |= COMPLETE;
+@@ -352,7 +349,7 @@
+ }
+ 
+ /* Add an entry to the 'ipq' queue for a newly received IP datagram. */
+-static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph)
++static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user)
+ {
+ 	struct ipq *qp;
+ 
+@@ -364,6 +361,7 @@
+ 	qp->id = iph->id;
+ 	qp->saddr = iph->saddr;
+ 	qp->daddr = iph->daddr;
++	qp->user = user;
+ 	qp->len = 0;
+ 	qp->meat = 0;
+ 	qp->fragments = NULL;
+@@ -386,7 +384,7 @@
+ /* Find the correct entry in the "incomplete datagrams" queue for
+  * this IP datagram, and create new one, if nothing is found.
+  */
+-static inline struct ipq *ip_find(struct iphdr *iph)
++static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
+ {
+ 	__u16 id = iph->id;
+ 	__u32 saddr = iph->saddr;
+@@ -400,7 +398,8 @@
+ 		if(qp->id == id		&&
+ 		   qp->saddr == saddr	&&
+ 		   qp->daddr == daddr	&&
+-		   qp->protocol == protocol) {
++		   qp->protocol == protocol &&
++		   qp->user == user) {
+ 			atomic_inc(&qp->refcnt);
+ 			read_unlock(&ipfrag_lock);
+ 			return qp;
+@@ -408,7 +407,7 @@
+ 	}
+ 	read_unlock(&ipfrag_lock);
+ 
+-	return ip_frag_create(hash, iph);
++	return ip_frag_create(hash, iph, user);
+ }
+ 
+ /* Add new segment to existing queue. */
+@@ -642,7 +641,7 @@
+ }
+ 
+ /* Process an incoming IP datagram fragment. */
+-struct sk_buff *ip_defrag(struct sk_buff *skb)
++struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)
+ {
+ 	struct iphdr *iph = skb->nh.iph;
+ 	struct ipq *qp;
+@@ -657,7 +656,7 @@
+ 	dev = skb->dev;
+ 
+ 	/* Lookup (or create) queue header */
+-	if ((qp = ip_find(iph)) != NULL) {
++	if ((qp = ip_find(iph, user)) != NULL) {
+ 		struct sk_buff *ret = NULL;
+ 
+ 		spin_lock(&qp->lock);
+@@ -689,10 +688,4 @@
+ 	add_timer(&ipfrag_secret_timer);
+ }
+ 
+-void ipfrag_flush(void)
+-{
+-	__ip_evictor(0);
+-}
+-
+ EXPORT_SYMBOL(ip_defrag);
+-EXPORT_SYMBOL(ipfrag_flush);
+diff -Nru a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
+--- a/net/ipv4/ip_input.c	2005-02-18 18:05:57 -08:00
++++ b/net/ipv4/ip_input.c	2005-02-18 18:05:57 -08:00
+@@ -172,7 +172,7 @@
+ 		    (!sk->sk_bound_dev_if ||
+ 		     sk->sk_bound_dev_if == skb->dev->ifindex)) {
+ 			if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+-				skb = ip_defrag(skb);
++				skb = ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN);
+ 				if (skb == NULL) {
+ 					read_unlock(&ip_ra_lock);
+ 					return 1;
+@@ -273,7 +273,7 @@
+ 	 */
+ 
+ 	if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+-		skb = ip_defrag(skb);
++		skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER);
+ 		if (!skb)
+ 			return 0;
+ 	}
+diff -Nru a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
+--- a/net/ipv4/ipvs/ip_vs_core.c	2005-02-18 18:05:57 -08:00
++++ b/net/ipv4/ipvs/ip_vs_core.c	2005-02-18 18:05:57 -08:00
+@@ -544,9 +544,9 @@
+ }
+ 
+ static inline struct sk_buff *
+-ip_vs_gather_frags(struct sk_buff *skb)
++ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
+ {
+-	skb = ip_defrag(skb);
++	skb = ip_defrag(skb, user);
+ 	if (skb)
+ 		ip_send_check(skb->nh.iph);
+ 	return skb;
+@@ -620,7 +620,7 @@
+ 
+ 	/* reassemble IP fragments */
+ 	if (skb->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) {
+-		skb = ip_vs_gather_frags(skb);
++		skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
+ 		if (!skb)
+ 			return NF_STOLEN;
+ 		*pskb = skb;
+@@ -759,7 +759,7 @@
+ 	/* reassemble IP fragments */
+ 	if (unlikely(iph->frag_off & __constant_htons(IP_MF|IP_OFFSET) &&
+ 		     !pp->dont_defrag)) {
+-		skb = ip_vs_gather_frags(skb);
++		skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
+ 		if (!skb)
+ 			return NF_STOLEN;
+ 		iph = skb->nh.iph;
+@@ -839,7 +839,8 @@
+  *	forward to the right destination host if relevant.
+  *	Currently handles error types - unreachable, quench, ttl exceeded.
+  */
+-static int ip_vs_in_icmp(struct sk_buff **pskb, int *related)
++static int 
++ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
+ {
+ 	struct sk_buff *skb = *pskb;
+ 	struct iphdr *iph;
+@@ -853,7 +854,9 @@
+ 
+ 	/* reassemble IP fragments */
+ 	if (skb->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) {
+-		skb = ip_vs_gather_frags(skb);
++		skb = ip_vs_gather_frags(skb,
++		                         hooknum == NF_IP_LOCAL_IN ?
++					 IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD);
+ 		if (!skb)
+ 			return NF_STOLEN;
+ 		*pskb = skb;
+@@ -962,7 +965,7 @@
+ 
+ 	iph = skb->nh.iph;
+ 	if (unlikely(iph->protocol == IPPROTO_ICMP)) {
+-		int related, verdict = ip_vs_in_icmp(pskb, &related);
++		int related, verdict = ip_vs_in_icmp(pskb, &related, hooknum);
+ 
+ 		if (related)
+ 			return verdict;
+@@ -1057,7 +1060,7 @@
+ 	if ((*pskb)->nh.iph->protocol != IPPROTO_ICMP)
+ 		return NF_ACCEPT;
+ 
+-	return ip_vs_in_icmp(pskb, &r);
++	return ip_vs_in_icmp(pskb, &r, hooknum);
+ }
+ 
+ 
+diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
+--- a/net/ipv4/netfilter/ip_conntrack_core.c	2005-02-18 18:05:57 -08:00
++++ b/net/ipv4/netfilter/ip_conntrack_core.c	2005-02-18 18:05:57 -08:00
+@@ -936,29 +936,22 @@
+ 	}
+ }
+ 
+-int ip_ct_no_defrag;
+-
+ /* Returns new sk_buff, or NULL */
+ struct sk_buff *
+-ip_ct_gather_frags(struct sk_buff *skb)
++ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user)
+ {
+ 	struct sock *sk = skb->sk;
+ #ifdef CONFIG_NETFILTER_DEBUG
+ 	unsigned int olddebug = skb->nf_debug;
+ #endif
+ 
+-	if (unlikely(ip_ct_no_defrag)) {
+-		kfree_skb(skb);
+-		return NULL;
+-	}
+-
+ 	if (sk) {
+ 		sock_hold(sk);
+ 		skb_orphan(skb);
+ 	}
+ 
+ 	local_bh_disable(); 
+-	skb = ip_defrag(skb);
++	skb = ip_defrag(skb, user);
+ 	local_bh_enable();
+ 
+ 	if (!skb) {
+diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
+--- a/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-02-18 18:05:57 -08:00
++++ b/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-02-18 18:05:57 -08:00
+@@ -391,7 +391,10 @@
+ 
+ 	/* Gather fragments. */
+ 	if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+-		*pskb = ip_ct_gather_frags(*pskb);
++		*pskb = ip_ct_gather_frags(*pskb,
++		                           hooknum == NF_IP_PRE_ROUTING ? 
++					   IP_DEFRAG_CONNTRACK_IN :
++					   IP_DEFRAG_CONNTRACK_OUT);
+ 		if (!*pskb)
+ 			return NF_STOLEN;
+ 	}
+@@ -823,12 +826,6 @@
+  cleanup_defraglocalops:
+ 	nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
+  cleanup_defragops:
+-	/* Frag queues may hold fragments with skb->dst == NULL */
+-	ip_ct_no_defrag = 1;
+-	smp_wmb();
+-	local_bh_disable();
+-	ipfrag_flush();
+-	local_bh_enable();
+ 	nf_unregister_hook(&ip_conntrack_defrag_ops);
+  cleanup_proc_stat:
+ #ifdef CONFIG_PROC_FS
+diff -Nru a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
+--- a/net/ipv4/netfilter/ip_nat_standalone.c	2005-02-18 18:05:57 -08:00
++++ b/net/ipv4/netfilter/ip_nat_standalone.c	2005-02-18 18:05:57 -08:00
+@@ -195,7 +195,7 @@
+ 	   I'm starting to have nightmares about fragments.  */
+ 
+ 	if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+-		*pskb = ip_ct_gather_frags(*pskb);
++		*pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT);
+ 
+ 		if (!*pskb)
+ 			return NF_STOLEN;

Added: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-4.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-4.dpatch	2005-02-26 12:20:34 UTC (rev 2573)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/ipv4-fragment-queues-4.dpatch	2005-02-27 05:06:47 UTC (rev 2574)
@@ -0,0 +1,16 @@
+# origin: Horms <horms@debian.org>
+# description: fix for ipfras queue's for ip_fw_compat.c
+# inclusion: This code does not seem to be upstream any more
+# revision date: 2005-02-23
+--- a/net/ipv4/netfilter/ip_fw_compat.c.unedited	2005-02-23 11:56:51.000000000 +0900
++++ b/net/ipv4/netfilter/ip_fw_compat.c	2005-02-23 11:56:53.000000000 +0900
+@@ -80,7 +80,8 @@ fw_in(unsigned int hooknum,
+ 					  &redirpt, pskb);
+ 
+ 		if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+-			*pskb = ip_ct_gather_frags(*pskb);
++			*pskb = ip_ct_gather_frags(*pskb, 
++					IP_DEFRAG_CONNTRACK_IN);
+ 
+ 			if (!*pskb)
+ 				return NF_STOLEN;

Modified: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-14
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-14	2005-02-26 12:20:34 UTC (rev 2573)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-14	2005-02-27 05:06:47 UTC (rev 2574)
@@ -12,3 +12,9 @@
 + 025-track_dummy_capability.dpatch
 + 027-track_dummy_capability-2.dpatch
 + nls-table-overflow.dpatch
++ outs.dpatch
++ setsid-race.dpatch
++ ipv4-fragment-queues-1.dpatch
++ ipv4-fragment-queues-2.dpatch
++ ipv4-fragment-queues-3.dpatch
++ ipv4-fragment-queues-4.dpatch

Modified: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-9
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-9	2005-02-26 12:20:34 UTC (rev 2573)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/series/2.6.8-9	2005-02-27 05:06:47 UTC (rev 2574)
@@ -26,4 +26,3 @@
 + sparc32-initrd-memcpy.dpatch
 + sparc64-sunsab-break-fix.dpatch
 + fs-partitions-check.dpatch
-+ outs.dpatch

Added: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/setsid-race.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/setsid-race.dpatch	2005-02-26 12:20:34 UTC (rev 2573)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/setsid-race.dpatch	2005-02-27 05:06:47 UTC (rev 2574)
@@ -0,0 +1,203 @@
+# origin: bk
+# key: 41ddda70CWJb5nNL71T4MOlG2sMG8A (linux-2.6)
+# description: fix setsid race [CAN-2005-0178]
+# inclusion: 2.6.11?
+# revision date: 2005-02-18
+
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+#   2005/01/06 16:40:16-08:00 alan@lxorguk.ukuu.org.uk 
+#   [PATCH] First cut at setsid/tty locking
+#   
+#   Use the existing "tty_sem" to protect against the process tty changes
+#   too.
+# 
+# drivers/char/tty_io.c
+#   2005/01/04 11:42:29-08:00 alan@lxorguk.ukuu.org.uk +29 -10
+#   First cut at setsid/tty locking
+# 
+# kernel/exit.c
+#   2005/01/04 10:45:27-08:00 alan@lxorguk.ukuu.org.uk +2 -0
+#   First cut at setsid/tty locking
+# 
+# kernel/sys.c
+#   2005/01/04 10:47:32-08:00 alan@lxorguk.ukuu.org.uk +2 -0
+#   First cut at setsid/tty locking
+# 
+diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
+--- a/drivers/char/tty_io.c	2005-02-18 17:33:57 -08:00
++++ b/drivers/char/tty_io.c	2005-02-18 17:33:57 -08:00
+@@ -918,9 +918,11 @@
+ 
+ 	lock_kernel();
+ 
++	down(&tty_sem);
+ 	tty = current->signal->tty;
+ 	if (tty) {
+ 		tty_pgrp = tty->pgrp;
++		up(&tty_sem);
+ 		if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
+ 			tty_vhangup(tty);
+ 	} else {
+@@ -928,6 +930,7 @@
+ 			kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit);
+ 			kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit);
+ 		}
++		up(&tty_sem);
+ 		unlock_kernel();	
+ 		return;
+ 	}
+@@ -937,14 +940,18 @@
+ 			kill_pg(tty_pgrp, SIGCONT, on_exit);
+ 	}
+ 
++	/* Must lock changes to tty_old_pgrp */
++	down(&tty_sem);
+ 	current->signal->tty_old_pgrp = 0;
+ 	tty->session = 0;
+ 	tty->pgrp = -1;
+ 
++	/* Now clear signal->tty under the lock */
+ 	read_lock(&tasklist_lock);
+ 	for_each_task_pid(current->signal->session, PIDTYPE_SID, p, l, pid)
+ 		p->signal->tty = NULL;
+ 	read_unlock(&tasklist_lock);
++	up(&tty_sem);
+ 	unlock_kernel();
+ }
+ 
+@@ -1172,12 +1179,6 @@
+ 	struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
+ 	int retval=0;
+ 
+-	/* 
+-	 * Check whether we need to acquire the tty semaphore to avoid
+-	 * race conditions.  For now, play it safe.
+-	 */
+-	down(&tty_sem);
+-
+ 	/* check whether we're reopening an existing tty */
+ 	if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
+ 		tty = devpts_get_tty(idx);
+@@ -1366,7 +1367,6 @@
+ 	
+ 	/* All paths come through here to release the semaphore */
+ end_init:
+-	up(&tty_sem);
+ 	return retval;
+ 
+ 	/* Release locally allocated memory ... nothing placed in slots */
+@@ -1562,9 +1562,14 @@
+ 	 * each iteration we avoid any problems.
+ 	 */
+ 	while (1) {
++		/* Guard against races with tty->count changes elsewhere and
++		   opens on /dev/tty */
++		   
++		down(&tty_sem);
+ 		tty_closing = tty->count <= 1;
+ 		o_tty_closing = o_tty &&
+ 			(o_tty->count <= (pty_master ? 1 : 0));
++		up(&tty_sem);
+ 		do_sleep = 0;
+ 
+ 		if (tty_closing) {
+@@ -1600,6 +1605,8 @@
+ 	 * both sides, and we've completed the last operation that could 
+ 	 * block, so it's safe to proceed with closing.
+ 	 */
++	 
++	down(&tty_sem);
+ 	if (pty_master) {
+ 		if (--o_tty->count < 0) {
+ 			printk(KERN_WARNING "release_dev: bad pty slave count "
+@@ -1613,7 +1620,8 @@
+ 		       tty->count, tty_name(tty, buf));
+ 		tty->count = 0;
+ 	}
+-
++	up(&tty_sem);
++	
+ 	/*
+ 	 * We've decremented tty->count, so we need to remove this file
+ 	 * descriptor off the tty->tty_files list; this serves two
+@@ -1760,10 +1768,14 @@
+ 	noctty = filp->f_flags & O_NOCTTY;
+ 	index  = -1;
+ 	retval = 0;
++	
++	down(&tty_sem);
+ 
+ 	if (device == MKDEV(TTYAUX_MAJOR,0)) {
+-		if (!current->signal->tty)
++		if (!current->signal->tty) {
++			up(&tty_sem);
+ 			return -ENXIO;
++		}
+ 		driver = current->signal->tty->driver;
+ 		index = current->signal->tty->index;
+ 		filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
+@@ -1788,14 +1800,18 @@
+ 			noctty = 1;
+ 			goto got_driver;
+ 		}
++		up(&tty_sem);
+ 		return -ENODEV;
+ 	}
+ 
+ 	driver = get_tty_driver(device, &index);
+-	if (!driver)
++	if (!driver) {
++		up(&tty_sem);
+ 		return -ENODEV;
++	}
+ got_driver:
+ 	retval = init_dev(driver, index, &tty);
++	up(&tty_sem);
+ 	if (retval)
+ 		return retval;
+ 
+@@ -1881,7 +1897,10 @@
+ 	}
+ 	up(&allocated_ptys_lock);
+ 
++	down(&tty_sem);
+ 	retval = init_dev(ptm_driver, index, &tty);
++	up(&tty_sem);
++	
+ 	if (retval)
+ 		goto out;
+ 
+diff -Nru a/kernel/exit.c b/kernel/exit.c
+--- a/kernel/exit.c	2005-02-18 17:33:57 -08:00
++++ b/kernel/exit.c	2005-02-18 17:33:57 -08:00
+@@ -332,7 +332,9 @@
+ 	exit_mm(current);
+ 
+ 	set_special_pids(1, 1);
++	down(&tty_sem);
+ 	current->signal->tty = NULL;
++	up(&tty_sem);
+ 
+ 	/* Block and flush all signals */
+ 	sigfillset(&blocked);
+diff -Nru a/kernel/sys.c b/kernel/sys.c
+--- a/kernel/sys.c	2005-02-18 17:33:57 -08:00
++++ b/kernel/sys.c	2005-02-18 17:33:57 -08:00
+@@ -1075,6 +1075,7 @@
+ 	if (!thread_group_leader(current))
+ 		return -EINVAL;
+ 
++	down(&tty_sem);
+ 	write_lock_irq(&tasklist_lock);
+ 
+ 	pid = find_pid(PIDTYPE_PGID, current->pid);
+@@ -1088,6 +1089,7 @@
+ 	err = process_group(current);
+ out:
+ 	write_unlock_irq(&tasklist_lock);
++	up(&tty_sem);
+ 	return err;
+ }
+