diff options
| author | Herbert Xu <herbert@gondor.apana.org.au> | 2010-07-05 10:50:08 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-07-05 23:08:06 -0400 |
| commit | 7f285fa78d4b81b8458f05e77fb6b46245121b4e (patch) | |
| tree | a4fa0d8e5cd102bb3aed7ad984de31e8a5f7575e | |
| parent | bcfcc450baaaa44afc1d3c51ef96a53338ff0eb2 (diff) | |
bridge br_multicast: BUG: unable to handle kernel NULL pointer dereference
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,
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/bridge/br_multicast.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 9d21d98ae5fa..27ae946363f1 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( | |||
| 99 | return NULL; | 99 | return NULL; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | ||
| 103 | struct net_bridge_mdb_htable *mdb, struct br_ip *dst) | ||
| 104 | { | ||
| 105 | if (!mdb) | ||
| 106 | return NULL; | ||
| 107 | |||
| 108 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); | ||
| 109 | } | ||
| 110 | |||
| 102 | static struct net_bridge_mdb_entry *br_mdb_ip4_get( | 111 | static struct net_bridge_mdb_entry *br_mdb_ip4_get( |
| 103 | struct net_bridge_mdb_htable *mdb, __be32 dst) | 112 | struct net_bridge_mdb_htable *mdb, __be32 dst) |
| 104 | { | 113 | { |
| @@ -107,7 +116,7 @@ static struct net_bridge_mdb_entry *br_mdb_ip4_get( | |||
| 107 | br_dst.u.ip4 = dst; | 116 | br_dst.u.ip4 = dst; |
| 108 | br_dst.proto = htons(ETH_P_IP); | 117 | br_dst.proto = htons(ETH_P_IP); |
| 109 | 118 | ||
| 110 | return __br_mdb_ip_get(mdb, &br_dst, __br_ip4_hash(mdb, dst)); | 119 | return br_mdb_ip_get(mdb, &br_dst); |
| 111 | } | 120 | } |
| 112 | 121 | ||
| 113 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 122 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| @@ -119,23 +128,17 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get( | |||
| 119 | ipv6_addr_copy(&br_dst.u.ip6, dst); | 128 | ipv6_addr_copy(&br_dst.u.ip6, dst); |
| 120 | br_dst.proto = htons(ETH_P_IPV6); | 129 | br_dst.proto = htons(ETH_P_IPV6); |
| 121 | 130 | ||
| 122 | return __br_mdb_ip_get(mdb, &br_dst, __br_ip6_hash(mdb, dst)); | 131 | return br_mdb_ip_get(mdb, &br_dst); |
| 123 | } | 132 | } |
| 124 | #endif | 133 | #endif |
| 125 | 134 | ||
| 126 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | ||
| 127 | struct net_bridge_mdb_htable *mdb, struct br_ip *dst) | ||
| 128 | { | ||
| 129 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); | ||
| 130 | } | ||
| 131 | |||
| 132 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, | 135 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, |
| 133 | struct sk_buff *skb) | 136 | struct sk_buff *skb) |
| 134 | { | 137 | { |
| 135 | struct net_bridge_mdb_htable *mdb = br->mdb; | 138 | struct net_bridge_mdb_htable *mdb = br->mdb; |
| 136 | struct br_ip ip; | 139 | struct br_ip ip; |
| 137 | 140 | ||
| 138 | if (!mdb || br->multicast_disabled) | 141 | if (br->multicast_disabled) |
| 139 | return NULL; | 142 | return NULL; |
| 140 | 143 | ||
| 141 | if (BR_INPUT_SKB_CB(skb)->igmp) | 144 | if (BR_INPUT_SKB_CB(skb)->igmp) |
