Skip to content

Commit 9ed973c

Browse files
T-Xdavem330
authored andcommitted
bridge: multicast: add sanity check for general query destination
General IGMP and MLD queries are supposed to have the multicast link-local all-nodes address as their destination according to RFC2236 section 9, RFC3376 section 4.1.12/9.1, RFC2710 section 8 and RFC3810 section 5.1.15. Without this check, such malformed IGMP/MLD queries can result in a denial of service: The queries are ignored by most IGMP/MLD listeners therefore they will not respond with an IGMP/MLD report. However, without this patch these malformed MLD queries would enable the snooping part in the bridge code, potentially shutting down the according ports towards these hosts for multicast traffic as the bridge did not learn about these listeners. Reported-by: Jan Stancek <[email protected]> Signed-off-by: Linus Lüssing <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c3f9b01 commit 9ed973c

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

net/bridge/br_multicast.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,14 @@ static int br_ip4_multicast_query(struct net_bridge *br,
11811181
IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
11821182
}
11831183

1184+
/* RFC2236+RFC3376 (IGMPv2+IGMPv3) require the multicast link layer
1185+
* all-systems destination addresses (224.0.0.1) for general queries
1186+
*/
1187+
if (!group && iph->daddr != htonl(INADDR_ALLHOSTS_GROUP)) {
1188+
err = -EINVAL;
1189+
goto out;
1190+
}
1191+
11841192
br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr,
11851193
max_delay);
11861194

@@ -1228,6 +1236,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
12281236
unsigned long max_delay;
12291237
unsigned long now = jiffies;
12301238
const struct in6_addr *group = NULL;
1239+
bool is_general_query;
12311240
int err = 0;
12321241

12331242
spin_lock(&br->multicast_lock);
@@ -1262,6 +1271,16 @@ static int br_ip6_multicast_query(struct net_bridge *br,
12621271
max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL);
12631272
}
12641273

1274+
is_general_query = group && ipv6_addr_any(group);
1275+
1276+
/* RFC2710+RFC3810 (MLDv1+MLDv2) require the multicast link layer
1277+
* all-nodes destination address (ff02::1) for general queries
1278+
*/
1279+
if (is_general_query && !ipv6_addr_is_ll_all_nodes(&ip6h->daddr)) {
1280+
err = -EINVAL;
1281+
goto out;
1282+
}
1283+
12651284
br_multicast_query_received(br, port, &br->ip6_querier,
12661285
!ipv6_addr_any(&ip6h->saddr), max_delay);
12671286

0 commit comments

Comments
 (0)