Patchwork bridge br_multicast: BUG: unable to handle kernel NULL pointer dereference

login
register
mail settings
Submitter Herbert Xu
Date July 6, 2010, 12:50 a.m.
Message ID <20100706005008.GA11699@gondor.apana.org.au>
Download mbox | patch
Permalink /patch/57961/
State Accepted
Delegated to: David Miller
Headers show

Comments

Herbert Xu - July 6, 2010, 12:50 a.m.
On Tue, Jul 06, 2010 at 08:48:35AM +0800, Herbert Xu wrote:
> 
> bridge: Restore NULL check in br_mdb_ip_get

Resend with proper attribution.

bridge: Restore NULL check in br_mdb_ip_get

Somewhere along the line the NULL check in br_mdb_ip_get went
AWOL, causing crashes when we receive an IGMP packet with no
multicast table allocated.

This patch restores it and ensures all br_mdb_*_get functions
use it.

Reported-by: Frank Arnold <frank.arnold@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


Thanks,
David Miller - July 6, 2010, 3:07 a.m.
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 6 Jul 2010 08:50:08 +0800

> On Tue, Jul 06, 2010 at 08:48:35AM +0800, Herbert Xu wrote:
>> 
>> bridge: Restore NULL check in br_mdb_ip_get
> 
> Resend with proper attribution.
> 
> bridge: Restore NULL check in br_mdb_ip_get
> 
> Somewhere along the line the NULL check in br_mdb_ip_get went
> AWOL, causing crashes when we receive an IGMP packet with no
> multicast table allocated.

It got removed by:

--------------------
commit 8ef2a9a59854994bace13b5c4f7edc2c8d4d124e
Author: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Date:   Sun Apr 18 12:42:07 2010 +0900

    bridge br_multicast: Make functions less ipv4 dependent.
    
    Introduce struct br_ip{} to store ip address and protocol
    and make functions more generic so that we can support
    both IPv4 and IPv6 with less pain.
    
    Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
--------------------

> This patch restores it and ensures all br_mdb_*_get functions
> use it.
> 
> Reported-by: Frank Arnold <frank.arnold@amd.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied, thanks.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 9d21d98..27ae946 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -99,6 +99,15 @@  static struct net_bridge_mdb_entry *__br_mdb_ip_get(
 	return NULL;
 }
 
+static struct net_bridge_mdb_entry *br_mdb_ip_get(
+	struct net_bridge_mdb_htable *mdb, struct br_ip *dst)
+{
+	if (!mdb)
+		return NULL;
+
+	return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst));
+}
+
 static struct net_bridge_mdb_entry *br_mdb_ip4_get(
 	struct net_bridge_mdb_htable *mdb, __be32 dst)
 {
@@ -107,7 +116,7 @@  static struct net_bridge_mdb_entry *br_mdb_ip4_get(
 	br_dst.u.ip4 = dst;
 	br_dst.proto = htons(ETH_P_IP);
 
-	return __br_mdb_ip_get(mdb, &br_dst, __br_ip4_hash(mdb, dst));
+	return br_mdb_ip_get(mdb, &br_dst);
 }
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -119,23 +128,17 @@  static struct net_bridge_mdb_entry *br_mdb_ip6_get(
 	ipv6_addr_copy(&br_dst.u.ip6, dst);
 	br_dst.proto = htons(ETH_P_IPV6);
 
-	return __br_mdb_ip_get(mdb, &br_dst, __br_ip6_hash(mdb, dst));
+	return br_mdb_ip_get(mdb, &br_dst);
 }
 #endif
 
-static struct net_bridge_mdb_entry *br_mdb_ip_get(
-	struct net_bridge_mdb_htable *mdb, struct br_ip *dst)
-{
-	return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst));
-}
-
 struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
 					struct sk_buff *skb)
 {
 	struct net_bridge_mdb_htable *mdb = br->mdb;
 	struct br_ip ip;
 
-	if (!mdb || br->multicast_disabled)
+	if (br->multicast_disabled)
 		return NULL;
 
 	if (BR_INPUT_SKB_CB(skb)->igmp)