* [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.