linux/net/bridge
Norbert Szetei 50e5c6605c net: bridge: mcast: fix use-after-free of a master VLAN's multicast context
br_multicast_toggle_one_vlan() clears BR_VLFLAG_MCAST_ENABLED under
br->multicast_lock before stopping a VLAN's multicast context.  That is
the teardown handshake: lockless readers gate on the flag through
br_multicast_ctx_should_use() -> br_multicast_ctx_vlan_disabled(), so
once it is cleared under the lock no reader can arm the context again.

For a master VLAN the handshake never runs.  __vlan_del() clears
BRIDGE_VLAN_INFO_BRENTRY before calling br_vlan_put_master(), so
br_multicast_toggle_one_vlan(masterv, false) returns early on
!br_vlan_is_brentry(vlan): the flag stays set and br->multicast_lock is
never taken.  br_vlan_put_master() then drains the context in
br_multicast_ctx_deinit() and frees the VLAN through call_rcu(), while a
reader still inside rcu_read_lock() sees the context as enabled and
re-arms it.  The port and port-VLAN branch of the function has no
br_vlan_is_brentry() test and flips the flag under br->multicast_lock,
so it is not affected.

The reader is the bridge transmit path.  For a master VLAN
br_multicast_rcv() selects brmctx = &vlan->br_mcast_ctx with
pmctx = NULL, so IGMP sent to the bridge device re-arms the context's
timers after br_multicast_ctx_deinit() has already stopped them.

  BUG: KASAN: slab-use-after-free in detach_if_pending+0x412/0x4a0
  Write of size 8 at addr ffff88810ac39918 by task brmc/601
   __mod_timer+0x51a/0xc50
   br_multicast_host_join+0x25b/0x390
   __br_multicast_add_group+0x468/0x530
   br_ip4_multicast_add_group+0x1a0/0x260
   br_multicast_rcv+0x2cda/0x61e0
   br_dev_xmit+0x6c4/0x1540
  Allocated by task 610:
   br_vlan_add+0x111/0xb40
   br_vlan_info+0x370/0x3e0
  Freed by task 0:
   kfree+0x1a7/0x4f0
   rcu_core+0x7dc/0x10a0

Only test br_vlan_is_brentry() when enabling, like the
br_multicast_ctx_vlan_global_disabled() test next to it.  Disabling then
always clears BR_VLFLAG_MCAST_ENABLED under br->multicast_lock before
br_multicast_ctx_deinit() drains the context.

Fixes: 7b54aaaf53 ("net: bridge: multicast: add vlan state initialization and control")
Cc: stable@vger.kernel.org
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/D400F6C7-543A-4B79-9E5B-D1D8974DE5C9@doyensec.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-27 12:35:03 -07:00
..
netfilter Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2026-08-13 11:00:14 -07:00
br_arp_nd_proxy.c net: bridge: arp/nd proxy: fix reading neigh ha 2026-08-20 14:23:06 -07:00
br_cfm_netlink.c bridge: cfm: reject invalid CCM interval at configuration time 2026-06-11 15:16:12 -07:00
br_cfm.c bridge: cfm: reject invalid CCM interval at configuration time 2026-06-11 15:16:12 -07:00
br_device.c bridge: Use direct pointer in br_is_nd_neigh_msg() 2026-08-07 16:32:46 -07:00
br_fdb.c net: bridge: use atomic ops to read/change p->flags (I) 2026-06-12 18:03:46 -07:00
br_forward.c net: bridge: use atomic ops to read/change p->flags (I) 2026-06-12 18:03:46 -07:00
br_if.c bridge: stp: Fix a potential use-after-free when deleting a bridge 2026-06-30 15:14:35 +02:00
br_input.c bridge: Use direct pointer in br_is_nd_neigh_msg() 2026-08-07 16:32:46 -07:00
br_ioctl.c bridge: provide lockless access to p->config_pending 2026-06-05 17:46:18 -07:00
br_mdb.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
br_mrp_netlink.c net: bridge: use atomic ops to read/change p->flags (II) 2026-06-12 18:03:46 -07:00
br_mrp_switchdev.c
br_mrp.c net: bridge: mrp: fix uninitialised bytes on the wire 2026-07-31 16:31:16 -07:00
br_mst.c net: bridge: fix MST static key usage 2025-11-06 07:32:17 -08:00
br_multicast_eht.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
br_multicast.c net: bridge: mcast: fix use-after-free of a master VLAN's multicast context 2026-08-27 12:35:03 -07:00
br_netfilter_hooks.c netfilter: br_netfilter: Reallocate headroom if necessary in neigh_hh_bridge() 2026-05-16 13:22:50 +02:00
br_netfilter_ipv6.c netfilter: remove nf_ipv6_ops and use direct function calls 2026-03-29 11:21:24 -07:00
br_netlink_tunnel.c net: bridge: Reject descending VLAN tunnel ranges 2026-08-20 11:32:44 -07:00
br_netlink.c net: bridge: use atomic ops to read/change p->flags (III) 2026-06-12 18:03:46 -07:00
br_nf_core.c bridge: netfilter: Fix forwarding of fragmented packets 2025-05-16 16:02:06 -07:00
br_private_cfm.h
br_private_mcast_eht.h
br_private_mrp.h
br_private_stp.h
br_private_tunnel.h bridge: always declare tunnel functions 2023-05-17 21:28:58 -07:00
br_private.h bridge: Validate NS/NA messages using ndisc_check_ns_na() 2026-08-07 16:32:46 -07:00
br_stp_bpdu.c net: bridge: use atomic ops to read/change p->flags (III) 2026-06-12 18:03:46 -07:00
br_stp_if.c bridge: provide lockless access to p->config_pending 2026-06-05 17:46:18 -07:00
br_stp_timer.c bridge: add a READ_ONCE() in br_timer_value() 2026-06-05 17:46:16 -07:00
br_stp.c bridge: stp: Fix a potential use-after-free when deleting a bridge 2026-06-30 15:14:35 +02:00
br_switchdev.c net: bridge: use atomic ops to read/change p->flags (III) 2026-06-12 18:03:46 -07:00
br_sysfs_br.c mm.git review status for linus..mm-nonmm-stable 2026-02-12 12:13:01 -08:00
br_sysfs_if.c bridge: use atomic ops to read/change p->flags in sysfs 2026-06-12 18:03:45 -07:00
br_vlan_options.c net: bridge: vlan: fix vlan range dumps starting with pvid 2026-07-22 10:23:18 -07:00
br_vlan_tunnel.c bridge: fix C-VLAN preservation in 802.1ad vlan_tunnel egress 2026-01-04 09:45:35 -08:00
br_vlan.c net: bridge: vlan: fix inverted default vlan notification 2026-08-17 18:27:14 -07:00
br.c net: remove unused ATM protocols and legacy ATM device drivers 2026-04-23 12:21:14 -07:00
Kconfig ipv6: convert CONFIG_IPV6 to built-in only and clean up Kconfigs 2026-03-29 11:21:22 -07:00
Makefile netfilter: add option for GCOV profiling 2026-05-24 22:55:47 +02:00