]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mlxsw: spectrum_router: Fix possible neighbour reference count leak
authorIdo Schimmel <idosch@nvidia.com>
Tue, 2 Dec 2025 17:44:11 +0000 (18:44 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 5 Dec 2025 01:53:48 +0000 (17:53 -0800)
mlxsw_sp_router_schedule_work() takes a reference on a neighbour,
expecting a work item to release it later on. However, we might fail to
schedule the work item, in which case the neighbour reference count will
be leaked.

Fix by taking the reference just before scheduling the work item. Note
that mlxsw_sp_router_schedule_work() can receive a NULL neighbour
pointer, but neigh_clone() handles that correctly.

Spotted during code review, did not actually observe the reference count
leak.

Fixes: 151b89f6025a ("mlxsw: spectrum_router: Reuse work neighbor initialization in work scheduler")
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/ec2934ae4aca187a8d8c9329a08ce93cca411378.1764695650.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

index a2033837182e863605491f1bc951a0f8cc74ae73..f4e9ecaeb104ffdde792d0987a601492538d3498 100644 (file)
@@ -2858,6 +2858,11 @@ static int mlxsw_sp_router_schedule_work(struct net *net,
        if (!net_work)
                return NOTIFY_BAD;
 
+       /* Take a reference to ensure the neighbour won't be destructed until
+        * we drop the reference in the work item.
+        */
+       neigh_clone(n);
+
        INIT_WORK(&net_work->work, cb);
        net_work->mlxsw_sp = router->mlxsw_sp;
        net_work->n = n;
@@ -2881,11 +2886,6 @@ static int mlxsw_sp_router_schedule_neigh_work(struct mlxsw_sp_router *router,
        struct net *net;
 
        net = neigh_parms_net(n->parms);
-
-       /* Take a reference to ensure the neighbour won't be destructed until we
-        * drop the reference in delayed work.
-        */
-       neigh_clone(n);
        return mlxsw_sp_router_schedule_work(net, router, n,
                                             mlxsw_sp_router_neigh_event_work);
 }