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;
+ }
+