All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikolay Aleksandrov <razor@blackwall.org>
To: Jun Yang <littleddfu@gmail.com>, Ido Schimmel <idosch@nvidia.com>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>,
	stable@vger.kernel.org, TencentOS Corvus AI <corvus@tencent.com>,
	bridge@lists.linux.dev, netdev@vger.kernel.org,
	Jun Yang <junvyyang@tencent.com>
Subject: Re: [PATCH net v3] net: bridge: mcast: don't truncate the port group walk on teardown
Date: Mon, 31 Aug 2026 15:37:05 +0300	[thread overview]
Message-ID: <e9dfedbf-b49c-436e-b01b-cd9cc02618cc@blackwall.org> (raw)
In-Reply-To: <20260831111330.199543-1-junvyyang@tencent.com>

On 31/08/2026 14:13, Jun Yang wrote:
> __br_multicast_disable_port_ctx() and br_multicast_del_port() walk
> port->mglist with hlist_for_each_entry_safe(). However,
> br_multicast_find_del_pg() can also delete other entries from the same
> list through br_multicast_fwd_src_remove() or __fwd_del_star_excl().
> 
> If such an entry is the iterator's saved next node, hlist_del_init()
> clears its ->next and terminates the walk early. The reproducer triggers
> this in both teardown walks, leaving port groups in the bridge mdb with
> a dangling ->key.port after del_nbp() frees the port:
> 
>    BUG: KASAN: slab-use-after-free in __mdb_fill_info+0x1191/0x1320
>     __mdb_fill_info+0x1191/0x1320
>     br_mdb_dump+0x594/0xe40
>     rtnl_mdb_dump+0x1cf/0x5d0
> 
> Use hlist_del_init_rcu() to unlink the group while preserving ->next.
> br_multicast_del_pg() and the teardown walks run under
> br->multicast_lock. The GC worker must acquire the same lock before
> detaching the group for destruction, so the node remains alive while
> the walk uses the preserved pointer.
> 
> Preserving ->next means a walk can now reach a group that an earlier
> iteration already deleted as a side effect. That group is off mp->ports,
> so br_multicast_find_del_pg() would fall through its port scan and hit
> the trailing WARN_ON(1). Skip such groups at the top of that helper: a
> port group is put on port->mglist when it is created and only unlinked
> when it is deleted, so hlist_unhashed() identifies exactly this case.
> 
> Fixes: b08123684bd5 ("net: bridge: mcast: install S,G entries automatically based on reports")
> Cc: stable@vger.kernel.org
> Suggested-by: Nikolay Aleksandrov <razor@blackwall.org>
> Reported-by: TencentOS Corvus AI <corvus@tencent.com>
> Assisted-by: tencentos-corvus-ai:kimi-k3
> Signed-off-by: Jun Yang <junvyyang@tencent.com>
> ---
> v3: skip already-unlinked groups at the top of br_multicast_find_del_pg()
>      instead of in each teardown walk, per Nikolay's suggestion, so the
>      preserved ->next no longer leads to the trailing WARN_ON(1).
> 
> v2: https://lore.kernel.org/netdev/20260826014200.362304-1-littleddfu@gmail.com/
>      Use hlist_del_init_rcu() to preserve ->next, as suggested by Nikolay,
>      instead of restarting the walks.
> 
> v1: https://lore.kernel.org/all/20260812113435.1854275-1-junvyyang@tencent.com/
> 
>   net/bridge/br_multicast.c | 13 ++++++++++++-
>   1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
> index 00aa9b2879d6..ea0a50eb8b77 100644
> --- a/net/bridge/br_multicast.c
> +++ b/net/bridge/br_multicast.c
> @@ -808,7 +808,11 @@ void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
>   	struct hlist_node *tmp;
>   
>   	rcu_assign_pointer(*pp, pg->next);
> -	hlist_del_init(&pg->mglist);
> +	/* Keep ->next (held under multicast_lock, freed later by the GC work):
> +	 * a port->mglist teardown walk may have latched this node as its next,
> +	 * and deleting other groups of the same port must not truncate it.
> +	 */
> +	hlist_del_init_rcu(&pg->mglist);
>   	br_multicast_eht_clean_sets(pg);
>   	hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node)
>   		br_multicast_del_group_src(ent, false);
> @@ -835,6 +839,13 @@ static void br_multicast_find_del_pg(struct net_bridge *br,
>   	struct net_bridge_mdb_entry *mp;
>   	struct net_bridge_port_group *p;
>   
> +	/* A teardown walk over port->mglist can reach a group that an earlier
> +	 * iteration already deleted as a side effect. It is off mp->ports by
> +	 * now, so skip it instead of falling through to the WARN_ON() below.
> +	 */
> +	if (hlist_unhashed(&pg->mglist))
> +		return;
> +
>   	mp = br_mdb_ip_get(br, &pg->key.addr);
>   	if (WARN_ON(!mp))
>   		return;


This should be fine, let's also see what sashiko thinks. :)

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>


  reply	other threads:[~2026-08-31 12:37 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31 11:13 [PATCH net v3] net: bridge: mcast: don't truncate the port group walk on teardown Jun Yang
2026-08-31 12:37 ` Nikolay Aleksandrov [this message]
2026-09-03  1:30 ` patchwork-bot+netdevbpf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e9dfedbf-b49c-436e-b01b-cd9cc02618cc@blackwall.org \
    --to=razor@blackwall.org \
    --cc=bridge@lists.linux.dev \
    --cc=corvus@tencent.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=idosch@nvidia.com \
    --cc=junvyyang@tencent.com \
    --cc=kuba@kernel.org \
    --cc=littleddfu@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.