On Fri, 28 Aug 2026 13:06:42 +0300 Nikolay Aleksandrov wrote:
> Sashiko reported a bug [1] that br_multicast_del_port_group unlists the
> port group not using proper rcu helper that preserves the next pointer and
> after that immediately frees the port group without waiting for rcu grace
> period. The only rcu walker of mglist is br_multicast_list_adjacent() and
> it turns out that function has always been buggy because mglist was never
> converted to RCU. Fix it by acquiring the bridge's multicast lock for the
> mglist walk. We can do a proper mglist rcu conversion later.
> 
> [1] 
> https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260826014200.362304-1-littleddfu%40gmail.com
> 
> Fixes: 07f8ac4a1e26 ("bridge: add export of multicast database adjacent to 
> net_dev")
> Signed-off-by: Nikolay Aleksandrov <[email protected]>
> ---
> We can do a proper mglist rcu conversion when net-next opens up.
> 
>  net/bridge/br_multicast.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
> index 3ef5d8bbf552..7fa5f4444c4c 100644
> --- a/net/bridge/br_multicast.c
> +++ b/net/bridge/br_multicast.c
> @@ -4967,15 +4967,19 @@ int br_multicast_list_adjacent(struct net_device *dev,
>               if (!port->dev || port->dev == dev)
>                       continue;
>  
> -             hlist_for_each_entry_rcu(group, &port->mglist, mglist) {
> +             spin_lock_bh(&br->multicast_lock);
> +             hlist_for_each_entry(group, &port->mglist, mglist) {
>                       entry = kmalloc_obj(*entry, GFP_ATOMIC);
> -                     if (!entry)
> +                     if (!entry) {
> +                             spin_unlock_bh(&br->multicast_lock);

Clashiko says that the only caller wants to see a ENOMEM which we never
produce, let's throw it in while we're touching this?

https://netdev-ai.bots.linux.dev/sashiko/#/patchset/[email protected]

>                               goto unlock;
> +                     }
>  
>                       entry->addr = group->key.addr;
>                       list_add(&entry->list, br_ip_list);
>                       count++;
>               }
> +             spin_unlock_bh(&br->multicast_lock);
>       }
>  
>  unlock:
-- 
pw-bot: cr

Reply via email to