Commit da744fd1 authored by Shay Drory's avatar Shay Drory Committed by Saeed Mahameed
Browse files

net/mlx5: Fix UAF in mlx5_eswitch_cleanup()



mlx5_eswitch_cleanup() is using esw right after freeing it for
releasing devlink_param.
Fix it by releasing the devlink_param before freeing the esw, and
adjust the create function accordingly.

Fixes: 3f908403 ("net/mlx5: Move esw multiport devlink param to eswitch code")
Reported-by: default avatarDan Carpenter <dan.carpenter@linaro.org>
Signed-off-by: default avatarShay Drory <shayd@nvidia.com>
Reviewed-by: default avatarAutomatic Verification <verifier@nvidia.com>
Reviewed-by: default avatarGal Pressman <gal@nvidia.com>
Reviewed-by: default avatarMoshe Shemesh <moshe@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent faaa5fd3
Loading
Loading
Loading
Loading
+8 −10
Original line number Original line Diff line number Diff line
@@ -1751,16 +1751,14 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
	if (!MLX5_VPORT_MANAGER(dev) && !MLX5_ESWITCH_MANAGER(dev))
	if (!MLX5_VPORT_MANAGER(dev) && !MLX5_ESWITCH_MANAGER(dev))
		return 0;
		return 0;


	esw = kzalloc(sizeof(*esw), GFP_KERNEL);
	if (!esw)
		return -ENOMEM;

	err = devl_params_register(priv_to_devlink(dev), mlx5_eswitch_params,
	err = devl_params_register(priv_to_devlink(dev), mlx5_eswitch_params,
				   ARRAY_SIZE(mlx5_eswitch_params));
				   ARRAY_SIZE(mlx5_eswitch_params));
	if (err)
	if (err)
		return err;
		goto free_esw;

	esw = kzalloc(sizeof(*esw), GFP_KERNEL);
	if (!esw) {
		err = -ENOMEM;
		goto unregister_param;
	}


	esw->dev = dev;
	esw->dev = dev;
	esw->manager_vport = mlx5_eswitch_manager_vport(dev);
	esw->manager_vport = mlx5_eswitch_manager_vport(dev);
@@ -1821,10 +1819,10 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
	if (esw->work_queue)
	if (esw->work_queue)
		destroy_workqueue(esw->work_queue);
		destroy_workqueue(esw->work_queue);
	debugfs_remove_recursive(esw->debugfs_root);
	debugfs_remove_recursive(esw->debugfs_root);
	kfree(esw);
unregister_param:
	devl_params_unregister(priv_to_devlink(dev), mlx5_eswitch_params,
	devl_params_unregister(priv_to_devlink(dev), mlx5_eswitch_params,
			       ARRAY_SIZE(mlx5_eswitch_params));
			       ARRAY_SIZE(mlx5_eswitch_params));
free_esw:
	kfree(esw);
	return err;
	return err;
}
}


@@ -1848,9 +1846,9 @@ void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw)
	esw_offloads_cleanup(esw);
	esw_offloads_cleanup(esw);
	mlx5_esw_vports_cleanup(esw);
	mlx5_esw_vports_cleanup(esw);
	debugfs_remove_recursive(esw->debugfs_root);
	debugfs_remove_recursive(esw->debugfs_root);
	kfree(esw);
	devl_params_unregister(priv_to_devlink(esw->dev), mlx5_eswitch_params,
	devl_params_unregister(priv_to_devlink(esw->dev), mlx5_eswitch_params,
			       ARRAY_SIZE(mlx5_eswitch_params));
			       ARRAY_SIZE(mlx5_eswitch_params));
	kfree(esw);
}
}


/* Vport Administration */
/* Vport Administration */