All of lore.kernel.org
 help / color / mirror / Atom feed
* [NETFILTER -stable 02/02]: bridge-netfilter: fix net_device refcnt leaks
@ 2008-01-29 18:08 Patrick McHardy
  2008-02-06 23:28 ` patch netfilter-bridge-netfilter-fix-net_device-refcnt-leaks.patch queued to -stable tree gregkh
  0 siblings, 1 reply; 2+ messages in thread
From: Patrick McHardy @ 2008-01-29 18:08 UTC (permalink / raw)
  To: stable; +Cc: David S. Miller, Netfilter Development Mailinglist

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



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

commit 6738b41be08760572a3fd013c57b4554de0080f5
Author: Patrick McHardy <kaber@trash.net>
Date:   Tue Jan 29 19:02:59 2008 +0100

    [NETFILTER]: bridge-netfilter: fix net_device refcnt leaks
    
    Upstream commit 2dc2f207fb251666d2396fe1a69272b307ecc333
    
    When packets are flood-forwarded to multiple output devices, the
    bridge-netfilter code reuses skb->nf_bridge for each clone to store
    the bridge port. When queueing packets using NFQUEUE netfilter takes
    a reference to skb->nf_bridge->physoutdev, which is overwritten
    when the packet is forwarded to the second port. This causes
    refcount unterflows for the first device and refcount leaks for all
    others. Additionally this provides incorrect data to the iptables
    physdev match.
    
    Unshare skb->nf_bridge by copying it if it is shared before assigning
    the physoutdev device.
    
    Reported, tested and based on initial patch by
    Jan Christoph Nordholz <hesso@pool.math.tu-berlin.de>.
    
    Signed-off-by: Patrick McHardy <kaber@trash.net>
    Signed-off-by: David S. Miller <davem@davemloft.net>

diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index ce48d8c..22545bd 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -142,6 +142,23 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
 	return skb->nf_bridge;
 }
 
+static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb)
+{
+	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+
+	if (atomic_read(&nf_bridge->use) > 1) {
+		struct nf_bridge_info *tmp = nf_bridge_alloc(skb);
+
+		if (tmp) {
+			memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info));
+			atomic_set(&tmp->use, 1);
+			nf_bridge_put(nf_bridge);
+		}
+		nf_bridge = tmp;
+	}
+	return nf_bridge;
+}
+
 static inline void nf_bridge_push_encap_header(struct sk_buff *skb)
 {
 	unsigned int len = nf_bridge_encap_header_len(skb);
@@ -644,6 +661,11 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
 	if (!skb->nf_bridge)
 		return NF_ACCEPT;
 
+	/* Need exclusive nf_bridge_info since we might have multiple
+	 * different physoutdevs. */
+	if (!nf_bridge_unshare(skb))
+		return NF_DROP;
+
 	parent = bridge_parent(out);
 	if (!parent)
 		return NF_DROP;
@@ -727,6 +749,11 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
 	if (!skb->nf_bridge)
 		return NF_ACCEPT;
 
+	/* Need exclusive nf_bridge_info since we might have multiple
+	 * different physoutdevs. */
+	if (!nf_bridge_unshare(skb))
+		return NF_DROP;
+
 	nf_bridge = skb->nf_bridge;
 	if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
 		return NF_ACCEPT;

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

* patch netfilter-bridge-netfilter-fix-net_device-refcnt-leaks.patch queued to -stable tree
  2008-01-29 18:08 [NETFILTER -stable 02/02]: bridge-netfilter: fix net_device refcnt leaks Patrick McHardy
@ 2008-02-06 23:28 ` gregkh
  0 siblings, 0 replies; 2+ messages in thread
From: gregkh @ 2008-02-06 23:28 UTC (permalink / raw)
  To: kaber, davem, gregkh, hesso, netfilter-devel; +Cc: stable, stable-commits


This is a note to let you know that we have just queued up the patch titled

     Subject: Netfilter: bridge-netfilter: fix net_device refcnt leaks

to the 2.6.23-stable tree.  Its filename is

     netfilter-bridge-netfilter-fix-net_device-refcnt-leaks.patch

A git repo of this tree can be found at 
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary


>From stable-bounces@linux.kernel.org Tue Jan 29 10:09:08 2008
From: Patrick McHardy <kaber@trash.net>
Date: Tue, 29 Jan 2008 19:08:28 +0100
Subject: Netfilter: bridge-netfilter: fix net_device refcnt leaks
To: stable@kernel.org
Cc: Netfilter Development Mailinglist <netfilter-devel@vger.kernel.org>, "David S. Miller" <davem@davemloft.net>
Message-ID: <479F6B9C.6000101@trash.net>


From: Patrick McHardy <kaber@trash.net>

[NETFILTER]: bridge-netfilter: fix net_device refcnt leaks

Upstream commit 2dc2f207fb251666d2396fe1a69272b307ecc333

When packets are flood-forwarded to multiple output devices, the
bridge-netfilter code reuses skb->nf_bridge for each clone to store
the bridge port. When queueing packets using NFQUEUE netfilter takes
a reference to skb->nf_bridge->physoutdev, which is overwritten
when the packet is forwarded to the second port. This causes
refcount unterflows for the first device and refcount leaks for all
others. Additionally this provides incorrect data to the iptables
physdev match.

Unshare skb->nf_bridge by copying it if it is shared before assigning
the physoutdev device.

Reported, tested and based on initial patch by
Jan Christoph Nordholz <hesso@pool.math.tu-berlin.de>.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 net/bridge/br_netfilter.c |   27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -142,6 +142,23 @@ static inline struct nf_bridge_info *nf_
 	return skb->nf_bridge;
 }
 
+static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb)
+{
+	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+
+	if (atomic_read(&nf_bridge->use) > 1) {
+		struct nf_bridge_info *tmp = nf_bridge_alloc(skb);
+
+		if (tmp) {
+			memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info));
+			atomic_set(&tmp->use, 1);
+			nf_bridge_put(nf_bridge);
+		}
+		nf_bridge = tmp;
+	}
+	return nf_bridge;
+}
+
 static inline void nf_bridge_push_encap_header(struct sk_buff *skb)
 {
 	unsigned int len = nf_bridge_encap_header_len(skb);
@@ -644,6 +661,11 @@ static unsigned int br_nf_forward_ip(uns
 	if (!skb->nf_bridge)
 		return NF_ACCEPT;
 
+	/* Need exclusive nf_bridge_info since we might have multiple
+	 * different physoutdevs. */
+	if (!nf_bridge_unshare(skb))
+		return NF_DROP;
+
 	parent = bridge_parent(out);
 	if (!parent)
 		return NF_DROP;
@@ -727,6 +749,11 @@ static unsigned int br_nf_local_out(unsi
 	if (!skb->nf_bridge)
 		return NF_ACCEPT;
 
+	/* Need exclusive nf_bridge_info since we might have multiple
+	 * different physoutdevs. */
+	if (!nf_bridge_unshare(skb))
+		return NF_DROP;
+
 	nf_bridge = skb->nf_bridge;
 	if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
 		return NF_ACCEPT;


Patches currently in stable-queue which might be from kaber@trash.net are

queue-2.6.23/netfilter-bridge-fix-double-post_routing-invocation.patch
queue-2.6.23/netfilter-bridge-netfilter-fix-net_device-refcnt-leaks.patch

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

end of thread, other threads:[~2008-02-06 23:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-29 18:08 [NETFILTER -stable 02/02]: bridge-netfilter: fix net_device refcnt leaks Patrick McHardy
2008-02-06 23:28 ` patch netfilter-bridge-netfilter-fix-net_device-refcnt-leaks.patch queued to -stable tree gregkh

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.