Skip to content

Commit 5515c34

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum_router: Fix use-after-free in router init / de-init
Several notifiers are registered as part of router initialization. Since some of these notifiers are registered before the end of the initialization, it is possible for them to access uninitialized or freed memory when processing notifications [1]. Additionally, some of these notifiers queue work items on a workqueue. If these work items are executed after the router was de-initialized, they will access freed memory. Fix both problems by moving the registration of the notifiers to the end of the router initialization and flush the work queue after they are unregistered. [1] BUG: KASAN: use-after-free in __mutex_lock_common kernel/locking/mutex.c:938 [inline] BUG: KASAN: use-after-free in __mutex_lock+0xeea/0x1340 kernel/locking/mutex.c:1103 Read of size 8 at addr ffff888038c3a6e0 by task kworker/u4:1/61 CPU: 1 PID: 61 Comm: kworker/u4:1 Not tainted 5.8.0-rc2+ #36 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 Workqueue: mlxsw_core_ordered mlxsw_sp_inet6addr_event_work Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xf6/0x16e lib/dump_stack.c:118 print_address_description.constprop.0+0x1c/0x250 mm/kasan/report.c:383 __kasan_report mm/kasan/report.c:513 [inline] kasan_report.cold+0x1f/0x37 mm/kasan/report.c:530 __mutex_lock_common kernel/locking/mutex.c:938 [inline] __mutex_lock+0xeea/0x1340 kernel/locking/mutex.c:1103 mlxsw_sp_inet6addr_event_work+0xb3/0x1b0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7123 process_one_work+0xa3e/0x17a0 kernel/workqueue.c:2269 worker_thread+0x9e/0x1050 kernel/workqueue.c:2415 kthread+0x355/0x470 kernel/kthread.c:291 ret_from_fork+0x22/0x30 arch/x86/entry/entry_64.S:293 Allocated by task 1298: save_stack+0x1b/0x40 mm/kasan/common.c:48 set_track mm/kasan/common.c:56 [inline] __kasan_kmalloc mm/kasan/common.c:494 [inline] __kasan_kmalloc.constprop.0+0xc2/0xd0 mm/kasan/common.c:467 kmalloc include/linux/slab.h:555 [inline] kzalloc include/linux/slab.h:669 [inline] mlxsw_sp_router_init+0xb2/0x1d20 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:8074 mlxsw_sp_init+0xbd8/0x3ac0 drivers/net/ethernet/mellanox/mlxsw/spectrum.c:2932 __mlxsw_core_bus_device_register+0x657/0x10d0 drivers/net/ethernet/mellanox/mlxsw/core.c:1375 mlxsw_core_bus_device_register drivers/net/ethernet/mellanox/mlxsw/core.c:1436 [inline] mlxsw_devlink_core_bus_device_reload_up+0xcd/0x150 drivers/net/ethernet/mellanox/mlxsw/core.c:1133 devlink_reload net/core/devlink.c:2959 [inline] devlink_reload+0x281/0x3b0 net/core/devlink.c:2944 devlink_nl_cmd_reload+0x2f1/0x7c0 net/core/devlink.c:2987 genl_family_rcv_msg_doit net/netlink/genetlink.c:691 [inline] genl_family_rcv_msg net/netlink/genetlink.c:736 [inline] genl_rcv_msg+0x611/0x9d0 net/netlink/genetlink.c:753 netlink_rcv_skb+0x152/0x440 net/netlink/af_netlink.c:2469 genl_rcv+0x24/0x40 net/netlink/genetlink.c:764 netlink_unicast_kernel net/netlink/af_netlink.c:1303 [inline] netlink_unicast+0x53a/0x750 net/netlink/af_netlink.c:1329 netlink_sendmsg+0x850/0xd90 net/netlink/af_netlink.c:1918 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg+0x150/0x190 net/socket.c:672 ____sys_sendmsg+0x6d8/0x840 net/socket.c:2363 ___sys_sendmsg+0xff/0x170 net/socket.c:2417 __sys_sendmsg+0xe5/0x1b0 net/socket.c:2450 do_syscall_64+0x56/0xa0 arch/x86/entry/common.c:359 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Freed by task 1348: save_stack+0x1b/0x40 mm/kasan/common.c:48 set_track mm/kasan/common.c:56 [inline] kasan_set_free_info mm/kasan/common.c:316 [inline] __kasan_slab_free+0x12c/0x170 mm/kasan/common.c:455 slab_free_hook mm/slub.c:1474 [inline] slab_free_freelist_hook mm/slub.c:1507 [inline] slab_free mm/slub.c:3072 [inline] kfree+0xe6/0x320 mm/slub.c:4063 mlxsw_sp_fini+0x340/0x4e0 drivers/net/ethernet/mellanox/mlxsw/spectrum.c:3132 mlxsw_core_bus_device_unregister+0x16c/0x6d0 drivers/net/ethernet/mellanox/mlxsw/core.c:1474 mlxsw_devlink_core_bus_device_reload_down+0x8e/0xc0 drivers/net/ethernet/mellanox/mlxsw/core.c:1123 devlink_reload+0xc6/0x3b0 net/core/devlink.c:2952 devlink_nl_cmd_reload+0x2f1/0x7c0 net/core/devlink.c:2987 genl_family_rcv_msg_doit net/netlink/genetlink.c:691 [inline] genl_family_rcv_msg net/netlink/genetlink.c:736 [inline] genl_rcv_msg+0x611/0x9d0 net/netlink/genetlink.c:753 netlink_rcv_skb+0x152/0x440 net/netlink/af_netlink.c:2469 genl_rcv+0x24/0x40 net/netlink/genetlink.c:764 netlink_unicast_kernel net/netlink/af_netlink.c:1303 [inline] netlink_unicast+0x53a/0x750 net/netlink/af_netlink.c:1329 netlink_sendmsg+0x850/0xd90 net/netlink/af_netlink.c:1918 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg+0x150/0x190 net/socket.c:672 ____sys_sendmsg+0x6d8/0x840 net/socket.c:2363 ___sys_sendmsg+0xff/0x170 net/socket.c:2417 __sys_sendmsg+0xe5/0x1b0 net/socket.c:2450 do_syscall_64+0x56/0xa0 arch/x86/entry/common.c:359 entry_SYSCALL_64_after_hwframe+0x44/0xa9 The buggy address belongs to the object at ffff888038c3a000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 1760 bytes inside of 2048-byte region [ffff888038c3a000, ffff888038c3a800) The buggy address belongs to the page: page:ffffea0000e30e00 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 head:ffffea0000e30e00 order:3 compound_mapcount:0 compound_pincount:0 flags: 0x100000000010200(slab|head) raw: 0100000000010200 dead000000000100 dead000000000122 ffff88806c40c000 raw: 0000000000000000 0000000000080008 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888038c3a580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888038c3a600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff888038c3a680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff888038c3a700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888038c3a780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb Fixes: 965fa8e ("mlxsw: spectrum_router: Make RIF deletion more robust") Signed-off-by: Ido Schimmel <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3c8ce24 commit 5515c34

File tree

1 file changed

+26
-24
lines changed

1 file changed

+26
-24
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8069,16 +8069,6 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
80698069
mlxsw_sp->router = router;
80708070
router->mlxsw_sp = mlxsw_sp;
80718071

8072-
router->inetaddr_nb.notifier_call = mlxsw_sp_inetaddr_event;
8073-
err = register_inetaddr_notifier(&router->inetaddr_nb);
8074-
if (err)
8075-
goto err_register_inetaddr_notifier;
8076-
8077-
router->inet6addr_nb.notifier_call = mlxsw_sp_inet6addr_event;
8078-
err = register_inet6addr_notifier(&router->inet6addr_nb);
8079-
if (err)
8080-
goto err_register_inet6addr_notifier;
8081-
80828072
INIT_LIST_HEAD(&mlxsw_sp->router->nexthop_neighs_list);
80838073
err = __mlxsw_sp_router_init(mlxsw_sp);
80848074
if (err)
@@ -8119,12 +8109,6 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
81198109
if (err)
81208110
goto err_neigh_init;
81218111

8122-
mlxsw_sp->router->netevent_nb.notifier_call =
8123-
mlxsw_sp_router_netevent_event;
8124-
err = register_netevent_notifier(&mlxsw_sp->router->netevent_nb);
8125-
if (err)
8126-
goto err_register_netevent_notifier;
8127-
81288112
err = mlxsw_sp_mp_hash_init(mlxsw_sp);
81298113
if (err)
81308114
goto err_mp_hash_init;
@@ -8133,6 +8117,22 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
81338117
if (err)
81348118
goto err_dscp_init;
81358119

8120+
router->inetaddr_nb.notifier_call = mlxsw_sp_inetaddr_event;
8121+
err = register_inetaddr_notifier(&router->inetaddr_nb);
8122+
if (err)
8123+
goto err_register_inetaddr_notifier;
8124+
8125+
router->inet6addr_nb.notifier_call = mlxsw_sp_inet6addr_event;
8126+
err = register_inet6addr_notifier(&router->inet6addr_nb);
8127+
if (err)
8128+
goto err_register_inet6addr_notifier;
8129+
8130+
mlxsw_sp->router->netevent_nb.notifier_call =
8131+
mlxsw_sp_router_netevent_event;
8132+
err = register_netevent_notifier(&mlxsw_sp->router->netevent_nb);
8133+
if (err)
8134+
goto err_register_netevent_notifier;
8135+
81368136
mlxsw_sp->router->fib_nb.notifier_call = mlxsw_sp_router_fib_event;
81378137
err = register_fib_notifier(mlxsw_sp_net(mlxsw_sp),
81388138
&mlxsw_sp->router->fib_nb,
@@ -8143,10 +8143,15 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
81438143
return 0;
81448144

81458145
err_register_fib_notifier:
8146-
err_dscp_init:
8147-
err_mp_hash_init:
81488146
unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
81498147
err_register_netevent_notifier:
8148+
unregister_inet6addr_notifier(&router->inet6addr_nb);
8149+
err_register_inet6addr_notifier:
8150+
unregister_inetaddr_notifier(&router->inetaddr_nb);
8151+
err_register_inetaddr_notifier:
8152+
mlxsw_core_flush_owq();
8153+
err_dscp_init:
8154+
err_mp_hash_init:
81508155
mlxsw_sp_neigh_fini(mlxsw_sp);
81518156
err_neigh_init:
81528157
mlxsw_sp_vrs_fini(mlxsw_sp);
@@ -8165,10 +8170,6 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
81658170
err_rifs_init:
81668171
__mlxsw_sp_router_fini(mlxsw_sp);
81678172
err_router_init:
8168-
unregister_inet6addr_notifier(&router->inet6addr_nb);
8169-
err_register_inet6addr_notifier:
8170-
unregister_inetaddr_notifier(&router->inetaddr_nb);
8171-
err_register_inetaddr_notifier:
81728173
mutex_destroy(&mlxsw_sp->router->lock);
81738174
kfree(mlxsw_sp->router);
81748175
return err;
@@ -8179,6 +8180,9 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
81798180
unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp),
81808181
&mlxsw_sp->router->fib_nb);
81818182
unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
8183+
unregister_inet6addr_notifier(&mlxsw_sp->router->inet6addr_nb);
8184+
unregister_inetaddr_notifier(&mlxsw_sp->router->inetaddr_nb);
8185+
mlxsw_core_flush_owq();
81828186
mlxsw_sp_neigh_fini(mlxsw_sp);
81838187
mlxsw_sp_vrs_fini(mlxsw_sp);
81848188
mlxsw_sp_mr_fini(mlxsw_sp);
@@ -8188,8 +8192,6 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
81888192
mlxsw_sp_ipips_fini(mlxsw_sp);
81898193
mlxsw_sp_rifs_fini(mlxsw_sp);
81908194
__mlxsw_sp_router_fini(mlxsw_sp);
8191-
unregister_inet6addr_notifier(&mlxsw_sp->router->inet6addr_nb);
8192-
unregister_inetaddr_notifier(&mlxsw_sp->router->inetaddr_nb);
81938195
mutex_destroy(&mlxsw_sp->router->lock);
81948196
kfree(mlxsw_sp->router);
81958197
}

0 commit comments

Comments
 (0)