Skip to content

Commit 99b4061

Browse files
Nikolay Aleksandrovkuba-moo
authored andcommitted
net: bridge: mcast: add and enforce query interval minimum
As reported[1] if query interval is set too low and we have multiple bridges or even a single bridge with multiple querier vlans configured we can crash the machine. Add a 1 second minimum which must be enforced by overwriting the value if set lower (i.e. without returning an error) to avoid breaking user-space. If that happens a log message is emitted to let the administrator know that the interval has been set to the minimum. The issue has been present since these intervals could be user-controlled. [1] https://lore.kernel.org/netdev/[email protected]/ Fixes: d902eee ("bridge: Add multicast count/interval sysfs entries") Reported-by: Eric Dumazet <[email protected]> Signed-off-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent fb7bc92 commit 99b4061

File tree

5 files changed

+22
-3
lines changed

5 files changed

+22
-3
lines changed

net/bridge/br_multicast.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4522,6 +4522,22 @@ int br_multicast_set_mld_version(struct net_bridge_mcast *brmctx,
45224522
}
45234523
#endif
45244524

4525+
void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx,
4526+
unsigned long val)
4527+
{
4528+
unsigned long intvl_jiffies = clock_t_to_jiffies(val);
4529+
4530+
if (intvl_jiffies < BR_MULTICAST_QUERY_INTVL_MIN) {
4531+
br_info(brmctx->br,
4532+
"trying to set multicast query interval below minimum, setting to %lu (%ums)\n",
4533+
jiffies_to_clock_t(BR_MULTICAST_QUERY_INTVL_MIN),
4534+
jiffies_to_msecs(BR_MULTICAST_QUERY_INTVL_MIN));
4535+
intvl_jiffies = BR_MULTICAST_QUERY_INTVL_MIN;
4536+
}
4537+
4538+
brmctx->multicast_query_interval = intvl_jiffies;
4539+
}
4540+
45254541
/**
45264542
* br_multicast_list_adjacent - Returns snooped multicast addresses
45274543
* @dev: The bridge port adjacent to which to retrieve addresses

net/bridge/br_netlink.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1357,7 +1357,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
13571357
if (data[IFLA_BR_MCAST_QUERY_INTVL]) {
13581358
u64 val = nla_get_u64(data[IFLA_BR_MCAST_QUERY_INTVL]);
13591359

1360-
br->multicast_ctx.multicast_query_interval = clock_t_to_jiffies(val);
1360+
br_multicast_set_query_intvl(&br->multicast_ctx, val);
13611361
}
13621362

13631363
if (data[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]) {

net/bridge/br_private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define BR_MAX_PORTS (1<<BR_PORT_BITS)
2929

3030
#define BR_MULTICAST_DEFAULT_HASH_MAX 4096
31+
#define BR_MULTICAST_QUERY_INTVL_MIN msecs_to_jiffies(1000)
3132

3233
#define BR_HWDOM_MAX BITS_PER_LONG
3334

@@ -963,6 +964,8 @@ int br_multicast_dump_querier_state(struct sk_buff *skb,
963964
int nest_attr);
964965
size_t br_multicast_querier_state_size(void);
965966
size_t br_rports_size(const struct net_bridge_mcast *brmctx);
967+
void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx,
968+
unsigned long val);
966969

967970
static inline bool br_group_is_l2(const struct br_ip *group)
968971
{

net/bridge/br_sysfs_br.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ static ssize_t multicast_query_interval_show(struct device *d,
658658
static int set_query_interval(struct net_bridge *br, unsigned long val,
659659
struct netlink_ext_ack *extack)
660660
{
661-
br->multicast_ctx.multicast_query_interval = clock_t_to_jiffies(val);
661+
br_multicast_set_query_intvl(&br->multicast_ctx, val);
662662
return 0;
663663
}
664664

net/bridge/br_vlan_options.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ static int br_vlan_process_global_one_opts(const struct net_bridge *br,
521521
u64 val;
522522

523523
val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]);
524-
v->br_mcast_ctx.multicast_query_interval = clock_t_to_jiffies(val);
524+
br_multicast_set_query_intvl(&v->br_mcast_ctx, val);
525525
*changed = true;
526526
}
527527
if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]) {

0 commit comments

Comments
 (0)