All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery
@ 2009-12-17 15:17 Patrick McHardy
  2009-12-17 15:18 ` [PATCH -stable 02/02]: netfilter: fix crashes in bridge netfilter caused by fragment jumps Patrick McHardy
  2009-12-17 16:14 ` [stable] [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery Greg KH
  0 siblings, 2 replies; 5+ messages in thread
From: Patrick McHardy @ 2009-12-17 15:17 UTC (permalink / raw)
  To: stable
  Cc: Netfilter Development Mailinglist, Linux Netdev List, David S. Miller

[-- Attachment #1: Type: text/plain, Size: 172 bytes --]

The following two patches for -stable fix some defragmentation bugs
in netfilter which can cause the kernel to crash in the bridge
netfilter code.

Please apply, thanks.



[-- Attachment #2: 01.diff --]
[-- Type: text/x-patch, Size: 5290 bytes --]

commit 04add9d712368c59f8736f954b1e06d3db0661ec
Author: Patrick McHardy <kaber@trash.net>
Date:   Thu Dec 17 16:08:02 2009 +0100

    ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery
    
    Upstream commit 0b5ccb2:
    
    Currently the same reassembly queue might be used for packets reassembled
    by conntrack in different positions in the stack (PREROUTING/LOCAL_OUT),
    as well as local delivery. This can cause "packet jumps" when the fragment
    completing a reassembled packet is queued from a different position in the
    stack than the previous ones.
    
    Add a "user" identifier to the reassembly queue key to seperate the queues
    of each caller, similar to what we do for IPv4.
    
    Signed-off-by: Patrick McHardy <kaber@trash.net>

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 8c31d8a..a496499 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -354,8 +354,15 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1,
 
 struct inet_frag_queue;
 
+enum ip6_defrag_users {
+	IP6_DEFRAG_LOCAL_DELIVER,
+	IP6_DEFRAG_CONNTRACK_IN,
+	IP6_DEFRAG_CONNTRACK_OUT,
+};
+
 struct ip6_create_arg {
 	__be32 id;
+	u32 user;
 	struct in6_addr *src;
 	struct in6_addr *dst;
 };
diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
index abc55ad..1ee717e 100644
--- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
@@ -9,7 +9,7 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
 
 extern int nf_ct_frag6_init(void);
 extern void nf_ct_frag6_cleanup(void);
-extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb);
+extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
 extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
 			       struct net_device *in,
 			       struct net_device *out,
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 5f2ec20..c0a82fe 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -187,6 +187,16 @@ out:
 	return nf_conntrack_confirm(skb);
 }
 
+static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
+						struct sk_buff *skb)
+{
+	if (hooknum == NF_INET_PRE_ROUTING)
+		return IP6_DEFRAG_CONNTRACK_IN;
+	else
+		return IP6_DEFRAG_CONNTRACK_OUT;
+
+}
+
 static unsigned int ipv6_defrag(unsigned int hooknum,
 				struct sk_buff *skb,
 				const struct net_device *in,
@@ -199,8 +209,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
 	if (skb->nfct)
 		return NF_ACCEPT;
 
-	reasm = nf_ct_frag6_gather(skb);
-
+	reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
 	/* queued */
 	if (reasm == NULL)
 		return NF_STOLEN;
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index f3aba25..4b6a539 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -170,13 +170,14 @@ out:
 /* Creation primitives. */
 
 static __inline__ struct nf_ct_frag6_queue *
-fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
+fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
 {
 	struct inet_frag_queue *q;
 	struct ip6_create_arg arg;
 	unsigned int hash;
 
 	arg.id = id;
+	arg.user = user;
 	arg.src = src;
 	arg.dst = dst;
 
@@ -561,7 +562,7 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
 	return 0;
 }
 
-struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
+struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 {
 	struct sk_buff *clone;
 	struct net_device *dev = skb->dev;
@@ -607,7 +608,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
 	if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
 		nf_ct_frag6_evictor();
 
-	fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
+	fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
 	if (fq == NULL) {
 		pr_debug("Can't find and can't create new queue\n");
 		goto ret_orig;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index da5bd0e..4d18699 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -72,6 +72,7 @@ struct frag_queue
 	struct inet_frag_queue	q;
 
 	__be32			id;		/* fragment id		*/
+	u32			user;
 	struct in6_addr		saddr;
 	struct in6_addr		daddr;
 
@@ -141,7 +142,7 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a)
 	struct ip6_create_arg *arg = a;
 
 	fq = container_of(q, struct frag_queue, q);
-	return (fq->id == arg->id &&
+	return (fq->id == arg->id && fq->user == arg->user &&
 			ipv6_addr_equal(&fq->saddr, arg->src) &&
 			ipv6_addr_equal(&fq->daddr, arg->dst));
 }
@@ -163,6 +164,7 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
 	struct ip6_create_arg *arg = a;
 
 	fq->id = arg->id;
+	fq->user = arg->user;
 	ipv6_addr_copy(&fq->saddr, arg->src);
 	ipv6_addr_copy(&fq->daddr, arg->dst);
 }
@@ -244,6 +246,7 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
 	unsigned int hash;
 
 	arg.id = id;
+	arg.user = IP6_DEFRAG_LOCAL_DELIVER;
 	arg.src = src;
 	arg.dst = dst;
 

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH -stable 02/02]: netfilter: fix crashes in bridge netfilter caused by fragment jumps
  2009-12-17 15:17 [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery Patrick McHardy
@ 2009-12-17 15:18 ` Patrick McHardy
  2009-12-17 16:14 ` [stable] [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery Greg KH
  1 sibling, 0 replies; 5+ messages in thread
From: Patrick McHardy @ 2009-12-17 15:18 UTC (permalink / raw)
  To: stable
  Cc: Netfilter Development Mailinglist, Linux Netdev List, David S. Miller

[-- Attachment #1: Type: text/plain, Size: 2 bytes --]




[-- Attachment #2: 02.diff --]
[-- Type: text/x-patch, Size: 4123 bytes --]

commit 182da5cb625b7e55bbf188c74861699f851feea8
Author: Patrick McHardy <kaber@trash.net>
Date:   Thu Dec 17 16:08:58 2009 +0100

    netfilter: fix crashes in bridge netfilter caused by fragment jumps
    
    Upstream commit 8fa9ff68:
    
    When fragments from bridge netfilter are passed to IPv4 or IPv6 conntrack
    and a reassembly queue with the same fragment key already exists from
    reassembling a similar packet received on a different device (f.i. with
    multicasted fragments), the reassembled packet might continue on a different
    codepath than where the head fragment originated. This can cause crashes
    in bridge netfilter when a fragment received on a non-bridge device (and
    thus with skb->nf_bridge == NULL) continues through the bridge netfilter
    code.
    
    Add a new reassembly identifier for packets originating from bridge
    netfilter and use it to put those packets in insolated queues.
    
    Fixes http://bugzilla.kernel.org/show_bug.cgi?id=14805
    
    Reported-and-Tested-by: Chong Qiao <qiaochong@loongson.cn>
    Signed-off-by: Patrick McHardy <kaber@trash.net>

diff --git a/include/net/ip.h b/include/net/ip.h
index 2f47e54..69db943 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -342,6 +342,7 @@ enum ip_defrag_users
 	IP_DEFRAG_CALL_RA_CHAIN,
 	IP_DEFRAG_CONNTRACK_IN,
 	IP_DEFRAG_CONNTRACK_OUT,
+	IP_DEFRAG_CONNTRACK_BRIDGE_IN,
 	IP_DEFRAG_VS_IN,
 	IP_DEFRAG_VS_OUT,
 	IP_DEFRAG_VS_FWD
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index a496499..639bbf0 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -358,6 +358,7 @@ enum ip6_defrag_users {
 	IP6_DEFRAG_LOCAL_DELIVER,
 	IP6_DEFRAG_CONNTRACK_IN,
 	IP6_DEFRAG_CONNTRACK_OUT,
+	IP6_DEFRAG_CONNTRACK_BRIDGE_IN,
 };
 
 struct ip6_create_arg {
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
index fa2d6b6..331ead3 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -14,6 +14,7 @@
 #include <net/route.h>
 #include <net/ip.h>
 
+#include <linux/netfilter_bridge.h>
 #include <linux/netfilter_ipv4.h>
 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
 
@@ -34,6 +35,20 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
 	return err;
 }
 
+static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
+					      struct sk_buff *skb)
+{
+#ifdef CONFIG_BRIDGE_NETFILTER
+	if (skb->nf_bridge &&
+	    skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
+		return IP_DEFRAG_CONNTRACK_BRIDGE_IN;
+#endif
+	if (hooknum == NF_INET_PRE_ROUTING)
+		return IP_DEFRAG_CONNTRACK_IN;
+	else
+		return IP_DEFRAG_CONNTRACK_OUT;
+}
+
 static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
 					  struct sk_buff *skb,
 					  const struct net_device *in,
@@ -50,10 +65,8 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
 #endif
 	/* Gather fragments. */
 	if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-		if (nf_ct_ipv4_gather_frags(skb,
-					    hooknum == NF_INET_PRE_ROUTING ?
-					    IP_DEFRAG_CONNTRACK_IN :
-					    IP_DEFRAG_CONNTRACK_OUT))
+		enum ip_defrag_users user = nf_ct_defrag_user(hooknum, skb);
+		if (nf_ct_ipv4_gather_frags(skb, user))
 			return NF_STOLEN;
 	}
 	return NF_ACCEPT;
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index c0a82fe..0956eba 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -20,6 +20,7 @@
 #include <net/ipv6.h>
 #include <net/inet_frag.h>
 
+#include <linux/netfilter_bridge.h>
 #include <linux/netfilter_ipv6.h>
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_helper.h>
@@ -190,6 +191,11 @@ out:
 static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
 						struct sk_buff *skb)
 {
+#ifdef CONFIG_BRIDGE_NETFILTER
+	if (skb->nf_bridge &&
+	    skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
+		return IP6_DEFRAG_CONNTRACK_BRIDGE_IN;
+#endif
 	if (hooknum == NF_INET_PRE_ROUTING)
 		return IP6_DEFRAG_CONNTRACK_IN;
 	else

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [stable] [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery
  2009-12-17 15:17 [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery Patrick McHardy
  2009-12-17 15:18 ` [PATCH -stable 02/02]: netfilter: fix crashes in bridge netfilter caused by fragment jumps Patrick McHardy
@ 2009-12-17 16:14 ` Greg KH
  2009-12-17 16:18   ` Patrick McHardy
  1 sibling, 1 reply; 5+ messages in thread
From: Greg KH @ 2009-12-17 16:14 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: stable, Linux Netdev List, Netfilter Development Mailinglist,
	David S. Miller

On Thu, Dec 17, 2009 at 04:17:24PM +0100, Patrick McHardy wrote:
> The following two patches for -stable fix some defragmentation bugs
> in netfilter which can cause the kernel to crash in the bridge
> netfilter code.
> 
> Please apply, thanks.

To which -stable tree?  .32, .31, and/or .27?

thanks,

greg "tree juggler" k-h

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [stable] [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery
  2009-12-17 16:14 ` [stable] [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery Greg KH
@ 2009-12-17 16:18   ` Patrick McHardy
  2009-12-17 16:26     ` Greg KH
  0 siblings, 1 reply; 5+ messages in thread
From: Patrick McHardy @ 2009-12-17 16:18 UTC (permalink / raw)
  To: Greg KH
  Cc: stable, Linux Netdev List, Netfilter Development Mailinglist,
	David S. Miller

Greg KH wrote:
> On Thu, Dec 17, 2009 at 04:17:24PM +0100, Patrick McHardy wrote:
>> The following two patches for -stable fix some defragmentation bugs
>> in netfilter which can cause the kernel to crash in the bridge
>> netfilter code.
>>
>> Please apply, thanks.
> 
> To which -stable tree?  .32, .31, and/or .27?

The patch is based on .32, but the bug affects all versions of the
kernel.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [stable] [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery
  2009-12-17 16:18   ` Patrick McHardy
@ 2009-12-17 16:26     ` Greg KH
  0 siblings, 0 replies; 5+ messages in thread
From: Greg KH @ 2009-12-17 16:26 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: Linux Netdev List, Netfilter Development Mailinglist, stable,
	David S. Miller

On Thu, Dec 17, 2009 at 05:18:06PM +0100, Patrick McHardy wrote:
> Greg KH wrote:
> > On Thu, Dec 17, 2009 at 04:17:24PM +0100, Patrick McHardy wrote:
> >> The following two patches for -stable fix some defragmentation bugs
> >> in netfilter which can cause the kernel to crash in the bridge
> >> netfilter code.
> >>
> >> Please apply, thanks.
> > 
> > To which -stable tree?  .32, .31, and/or .27?
> 
> The patch is based on .32, but the bug affects all versions of the
> kernel.

Thanks for letting me know, I'll queue it up for the next round of
kernels.

greg k-h

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-12-18 15:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-17 15:17 [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery Patrick McHardy
2009-12-17 15:18 ` [PATCH -stable 02/02]: netfilter: fix crashes in bridge netfilter caused by fragment jumps Patrick McHardy
2009-12-17 16:14 ` [stable] [PATCH -stable 01/02]: ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery Greg KH
2009-12-17 16:18   ` Patrick McHardy
2009-12-17 16:26     ` Greg KH

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.