diff options
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r-- | net/bridge/br_multicast.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 191ea66e4d92..6852f3c7009c 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -1279,6 +1279,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, | |||
1279 | struct br_ip saddr; | 1279 | struct br_ip saddr; |
1280 | unsigned long max_delay; | 1280 | unsigned long max_delay; |
1281 | unsigned long now = jiffies; | 1281 | unsigned long now = jiffies; |
1282 | unsigned int offset = skb_transport_offset(skb); | ||
1282 | __be32 group; | 1283 | __be32 group; |
1283 | int err = 0; | 1284 | int err = 0; |
1284 | 1285 | ||
@@ -1289,14 +1290,14 @@ static int br_ip4_multicast_query(struct net_bridge *br, | |||
1289 | 1290 | ||
1290 | group = ih->group; | 1291 | group = ih->group; |
1291 | 1292 | ||
1292 | if (skb->len == sizeof(*ih)) { | 1293 | if (skb->len == offset + sizeof(*ih)) { |
1293 | max_delay = ih->code * (HZ / IGMP_TIMER_SCALE); | 1294 | max_delay = ih->code * (HZ / IGMP_TIMER_SCALE); |
1294 | 1295 | ||
1295 | if (!max_delay) { | 1296 | if (!max_delay) { |
1296 | max_delay = 10 * HZ; | 1297 | max_delay = 10 * HZ; |
1297 | group = 0; | 1298 | group = 0; |
1298 | } | 1299 | } |
1299 | } else if (skb->len >= sizeof(*ih3)) { | 1300 | } else if (skb->len >= offset + sizeof(*ih3)) { |
1300 | ih3 = igmpv3_query_hdr(skb); | 1301 | ih3 = igmpv3_query_hdr(skb); |
1301 | if (ih3->nsrcs) | 1302 | if (ih3->nsrcs) |
1302 | goto out; | 1303 | goto out; |
@@ -1357,6 +1358,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
1357 | struct br_ip saddr; | 1358 | struct br_ip saddr; |
1358 | unsigned long max_delay; | 1359 | unsigned long max_delay; |
1359 | unsigned long now = jiffies; | 1360 | unsigned long now = jiffies; |
1361 | unsigned int offset = skb_transport_offset(skb); | ||
1360 | const struct in6_addr *group = NULL; | 1362 | const struct in6_addr *group = NULL; |
1361 | bool is_general_query; | 1363 | bool is_general_query; |
1362 | int err = 0; | 1364 | int err = 0; |
@@ -1366,8 +1368,8 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
1366 | (port && port->state == BR_STATE_DISABLED)) | 1368 | (port && port->state == BR_STATE_DISABLED)) |
1367 | goto out; | 1369 | goto out; |
1368 | 1370 | ||
1369 | if (skb->len == sizeof(*mld)) { | 1371 | if (skb->len == offset + sizeof(*mld)) { |
1370 | if (!pskb_may_pull(skb, sizeof(*mld))) { | 1372 | if (!pskb_may_pull(skb, offset + sizeof(*mld))) { |
1371 | err = -EINVAL; | 1373 | err = -EINVAL; |
1372 | goto out; | 1374 | goto out; |
1373 | } | 1375 | } |
@@ -1376,7 +1378,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, | |||
1376 | if (max_delay) | 1378 | if (max_delay) |
1377 | group = &mld->mld_mca; | 1379 | group = &mld->mld_mca; |
1378 | } else { | 1380 | } else { |
1379 | if (!pskb_may_pull(skb, sizeof(*mld2q))) { | 1381 | if (!pskb_may_pull(skb, offset + sizeof(*mld2q))) { |
1380 | err = -EINVAL; | 1382 | err = -EINVAL; |
1381 | goto out; | 1383 | goto out; |
1382 | } | 1384 | } |