)]}'
{
  "commit": "bdced577da71b118b6ed4242ebd47f81bf54d406",
  "tree": "d78d1cb2c0c8b49a48f3f1ba7368b9bfc2cf5c47",
  "parents": [
    "bb719f86be14b06c9640903586a9e244e5a8ce0d"
  ],
  "author": {
    "name": "Ido Schimmel",
    "email": "idosch@nvidia.com",
    "time": "Thu Jun 19 21:22:28 2025 +0300"
  },
  "committer": {
    "name": "Greg Kroah-Hartman",
    "email": "gregkh@linuxfoundation.org",
    "time": "Fri Jan 23 11:18:42 2026 +0100"
  },
  "message": "bridge: mcast: Fix use-after-free during router port configuration\n\ncommit 7544f3f5b0b58c396f374d060898b5939da31709 upstream.\n\nThe bridge maintains a global list of ports behind which a multicast\nrouter resides. The list is consulted during forwarding to ensure\nmulticast packets are forwarded to these ports even if the ports are not\nmember in the matching MDB entry.\n\nWhen per-VLAN multicast snooping is enabled, the per-port multicast\ncontext is disabled on each port and the port is removed from the global\nrouter port list:\n\n # ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1\n # ip link add name dummy1 up master br1 type dummy\n # ip link set dev dummy1 type bridge_slave mcast_router 2\n $ bridge -d mdb show | grep router\n router ports on br1: dummy1\n # ip link set dev br1 type bridge mcast_vlan_snooping 1\n $ bridge -d mdb show | grep router\n\nHowever, the port can be re-added to the global list even when per-VLAN\nmulticast snooping is enabled:\n\n # ip link set dev dummy1 type bridge_slave mcast_router 0\n # ip link set dev dummy1 type bridge_slave mcast_router 2\n $ bridge -d mdb show | grep router\n router ports on br1: dummy1\n\nSince commit 4b30ae9adb04 (\"net: bridge: mcast: re-implement\nbr_multicast_{enable, disable}_port functions\"), when per-VLAN multicast\nsnooping is enabled, multicast disablement on a port will disable the\nper-{port, VLAN} multicast contexts and not the per-port one. As a\nresult, a port will remain in the global router port list even after it\nis deleted. This will lead to a use-after-free [1] when the list is\ntraversed (when adding a new port to the list, for example):\n\n # ip link del dev dummy1\n # ip link add name dummy2 up master br1 type dummy\n # ip link set dev dummy2 type bridge_slave mcast_router 2\n\nSimilarly, stale entries can also be found in the per-VLAN router port\nlist. When per-VLAN multicast snooping is disabled, the per-{port, VLAN}\ncontexts are disabled on each port and the port is removed from the\nper-VLAN router port list:\n\n # ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 mcast_vlan_snooping 1\n # ip link add name dummy1 up master br1 type dummy\n # bridge vlan add vid 2 dev dummy1\n # bridge vlan global set vid 2 dev br1 mcast_snooping 1\n # bridge vlan set vid 2 dev dummy1 mcast_router 2\n $ bridge vlan global show dev br1 vid 2 | grep router\n       router ports: dummy1\n # ip link set dev br1 type bridge mcast_vlan_snooping 0\n $ bridge vlan global show dev br1 vid 2 | grep router\n\nHowever, the port can be re-added to the per-VLAN list even when\nper-VLAN multicast snooping is disabled:\n\n # bridge vlan set vid 2 dev dummy1 mcast_router 0\n # bridge vlan set vid 2 dev dummy1 mcast_router 2\n $ bridge vlan global show dev br1 vid 2 | grep router\n       router ports: dummy1\n\nWhen the VLAN is deleted from the port, the per-{port, VLAN} multicast\ncontext will not be disabled since multicast snooping is not enabled\non the VLAN. As a result, the port will remain in the per-VLAN router\nport list even after it is no longer member in the VLAN. This will lead\nto a use-after-free [2] when the list is traversed (when adding a new\nport to the list, for example):\n\n # ip link add name dummy2 up master br1 type dummy\n # bridge vlan add vid 2 dev dummy2\n # bridge vlan del vid 2 dev dummy1\n # bridge vlan set vid 2 dev dummy2 mcast_router 2\n\nFix these issues by removing the port from the relevant (global or\nper-VLAN) router port list in br_multicast_port_ctx_deinit(). The\nfunction is invoked during port deletion with the per-port multicast\ncontext and during VLAN deletion with the per-{port, VLAN} multicast\ncontext.\n\nNote that deleting the multicast router timer is not enough as it only\ntakes care of the temporary multicast router states (1 or 3) and not the\npermanent one (2).\n\n[1]\nBUG: KASAN: slab-out-of-bounds in br_multicast_add_router.part.0+0x3f1/0x560\nWrite of size 8 at addr ffff888004a67328 by task ip/384\n[...]\nCall Trace:\n \u003cTASK\u003e\n dump_stack_lvl+0x6f/0xa0\n print_address_description.constprop.0+0x6f/0x350\n print_report+0x108/0x205\n kasan_report+0xdf/0x110\n br_multicast_add_router.part.0+0x3f1/0x560\n br_multicast_set_port_router+0x74e/0xac0\n br_setport+0xa55/0x1870\n br_port_slave_changelink+0x95/0x120\n __rtnl_newlink+0x5e8/0xa40\n rtnl_newlink+0x627/0xb00\n rtnetlink_rcv_msg+0x6fb/0xb70\n netlink_rcv_skb+0x11f/0x350\n netlink_unicast+0x426/0x710\n netlink_sendmsg+0x75a/0xc20\n __sock_sendmsg+0xc1/0x150\n ____sys_sendmsg+0x5aa/0x7b0\n ___sys_sendmsg+0xfc/0x180\n __sys_sendmsg+0x124/0x1c0\n do_syscall_64+0xbb/0x360\n entry_SYSCALL_64_after_hwframe+0x4b/0x53\n\n[2]\nBUG: KASAN: slab-use-after-free in br_multicast_add_router.part.0+0x378/0x560\nRead of size 8 at addr ffff888009f00840 by task bridge/391\n[...]\nCall Trace:\n \u003cTASK\u003e\n dump_stack_lvl+0x6f/0xa0\n print_address_description.constprop.0+0x6f/0x350\n print_report+0x108/0x205\n kasan_report+0xdf/0x110\n br_multicast_add_router.part.0+0x378/0x560\n br_multicast_set_port_router+0x6f9/0xac0\n br_vlan_process_options+0x8b6/0x1430\n br_vlan_rtm_process_one+0x605/0xa30\n br_vlan_rtm_process+0x396/0x4c0\n rtnetlink_rcv_msg+0x2f7/0xb70\n netlink_rcv_skb+0x11f/0x350\n netlink_unicast+0x426/0x710\n netlink_sendmsg+0x75a/0xc20\n __sock_sendmsg+0xc1/0x150\n ____sys_sendmsg+0x5aa/0x7b0\n ___sys_sendmsg+0xfc/0x180\n __sys_sendmsg+0x124/0x1c0\n do_syscall_64+0xbb/0x360\n entry_SYSCALL_64_after_hwframe+0x4b/0x53\n\nFixes: 2796d846d74a (\"net: bridge: vlan: convert mcast router global option to per-vlan entry\")\nFixes: 4b30ae9adb04 (\"net: bridge: mcast: re-implement br_multicast_{enable, disable}_port functions\")\nReported-by: syzbot+7bfa4b72c6a5da128d32@syzkaller.appspotmail.com\nCloses: https://lore.kernel.org/all/684c18bd.a00a0220.279073.000b.GAE@google.com/T/\nSigned-off-by: Ido Schimmel \u003cidosch@nvidia.com\u003e\nLink: https://patch.msgid.link/20250619182228.1656906-1-idosch@nvidia.com\nSigned-off-by: Jakub Kicinski \u003ckuba@kernel.org\u003e\nSigned-off-by: Lee Jones \u003clee@kernel.org\u003e\nSigned-off-by: Greg Kroah-Hartman \u003cgregkh@linuxfoundation.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "0a00c3f578156b67019a3b12f51c24db7ac2008d",
      "old_mode": 33188,
      "old_path": "net/bridge/br_multicast.c",
      "new_id": "4227894e357920a3a5079ba950d022ef9c3be276",
      "new_mode": 33188,
      "new_path": "net/bridge/br_multicast.c"
    }
  ]
}
