Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5ce2a23 authored by Shalom Toledo's avatar Shalom Toledo Committed by Greg Kroah-Hartman
Browse files

mlxsw: core: Fix devlink unregister flow



[ Upstream commit a22712a962912faf257e857ab6857f56a93cfb34 ]

After a failed reload, the driver is still registered to devlink, its
devlink instance is still allocated and the 'reload_fail' flag is set.
Then, in the next reload try, the driver's allocated devlink instance will
be freed without unregistering from devlink and its components (e.g,
resources). This scenario can cause a use-after-free if the user tries to
execute command via devlink user-space tool.

Fix by not freeing the devlink instance during reload (failed or not).

Fixes: 24cc68ad ("mlxsw: core: Add support for reload")
Signed-off-by: default avatarShalom Toledo <shalomt@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a731a1e8
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -943,8 +943,8 @@ static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink,
					     mlxsw_core->bus,
					     mlxsw_core->bus_priv, true,
					     devlink);
	if (err)
		mlxsw_core->reload_fail = true;
	mlxsw_core->reload_fail = !!err;

	return err;
}

@@ -1083,8 +1083,15 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
{
	struct devlink *devlink = priv_to_devlink(mlxsw_core);

	if (mlxsw_core->reload_fail)
		goto reload_fail;
	if (mlxsw_core->reload_fail) {
		if (!reload)
			/* Only the parts that were not de-initialized in the
			 * failed reload attempt need to be de-initialized.
			 */
			goto reload_fail_deinit;
		else
			return;
	}

	if (mlxsw_core->driver->fini)
		mlxsw_core->driver->fini(mlxsw_core);
@@ -1098,9 +1105,12 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
	if (!reload)
		devlink_resources_unregister(devlink, NULL);
	mlxsw_core->bus->fini(mlxsw_core->bus_priv);
	if (reload)

	return;
reload_fail:

reload_fail_deinit:
	devlink_unregister(devlink);
	devlink_resources_unregister(devlink, NULL);
	devlink_free(devlink);
}
EXPORT_SYMBOL(mlxsw_core_bus_device_unregister);