hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8UZTK CVE: NA
--------------------------------
Get a UAF problem as following:
======================================================== BUG: KASAN: use-after-free in expire_timers+0x100/0x260 ... Call Trace: <IRQ> dump_stack+0xbe/0xfd print_address_description.constprop.0+0x19/0x170 ? expire_timers+0x100/0x260 __kasan_report.cold+0x6c/0x84 ? ipv6_mc_netdev_event+0x51/0x80 ? expire_timers+0x100/0x260 kasan_report+0x3a/0x50 expire_timers+0x100/0x260 run_timer_softirq+0x22c/0x550 ? expire_timers+0x260/0x260 ? pvclock_clocksource_read+0xf6/0x1d0 ? kvm_sched_clock_read+0x14/0x30 ? sched_clock+0x5/0x10 ? sched_clock_cpu+0x18/0x130 __do_softirq+0x104/0x42f asm_call_irq_on_stack+0xf/0x20 ... Allocated by task 26715: kasan_save_stack+0x1b/0x40 __kasan_kmalloc.constprop.0+0xf0/0x130 kvmalloc_node+0xc5/0x170 alloc_netdev_mqs+0x99/0x6b0 rtnl_create_link+0x170/0x510 __rtnl_newlink+0xc8a/0x10f0 rtnl_newlink+0x5a/0x90 rtnetlink_rcv_msg+0x303/0x780 netlink_rcv_skb+0xfd/0x2c0 netlink_unicast+0x2c1/0x3f0 netlink_sendmsg+0x537/0x950 __sock_sendmsg+0x10d/0x120 ____sys_sendmsg+0x519/0x590 ___sys_sendmsg+0xe9/0x150 __sys_sendmsg+0xea/0x190 do_syscall_64+0x30/0x40 entry_SYSCALL_64_after_hwframe+0x62/0xc7
Freed by task 26715: kasan_save_stack+0x1b/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x20/0x40 __kasan_slab_free.part.0+0x13f/0x1b0 kfree+0xce/0x860 kvfree+0x47/0x50 device_release+0x62/0x130 kobject_cleanup+0xb6/0x280 kobject_put+0xe0/0xf0 netdev_run_todo+0x440/0x6d0 rtnetlink_rcv_msg+0x313/0x780 netlink_rcv_skb+0xfd/0x2c0 netlink_unicast+0x2c1/0x3f0 netlink_sendmsg+0x537/0x950 __sock_sendmsg+0x10d/0x120 ____sys_sendmsg+0x519/0x590 ___sys_sendmsg+0xe9/0x150 __sys_sendmsg+0xea/0x190 do_syscall_64+0x30/0x40 entry_SYSCALL_64_after_hwframe+0x62/0xc7
Under closed state of bridge netdev, try to activate ip6_own_query.timer of bridge netdev by br_multicast_set_querier(), and delete bridge netdev immediately afterwards. Because the timer will not be deleted during bridge netdev deleting process. When the timer is not activated before bridge netdev is released, UAF will be triggered to access the timer in expire_timers().
Add br_multicast_stop() in br_multicast_dev_del() to delete the timer during bridge netdev deleting process as done in commit 613d61dbef8e ("net: bridge: vlan: add global and per-port multicast context").
Fixes: cc0fdd802859 ("bridge: separate querier and query timer into IGMP/IPv4 and MLD/IPv6 ones") Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com --- v2: - remove "Offering" item. --- net/bridge/br_multicast.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index e2b1bb3de4a1..f3886d5b7952 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -3357,6 +3357,7 @@ void br_multicast_dev_del(struct net_bridge *br) hlist_move_list(&br->mcast_gc_list, &deleted_head); spin_unlock_bh(&br->multicast_lock);
+ br_multicast_stop(br); br_multicast_gc(&deleted_head); cancel_work_sync(&br->mcast_gc_work);