The matchers are created and organized in groups, and the groups are managed by a hash list in shared object.
The creation order: 1. If no group, create the group and register it into the hash list. And create the list to save matchers. 2. If no matcher is found, register the matcher and increase the reference count of group. 3. If the matcher exists and can be reused, increase the reference counts of its group and itself. When dereferencing a matcher, the orders should be reversed. 1. Dereference the matcher and release it when not being used. 2. Dereference the group and release it when not being used. When the last flow rule on some group was trying to be destroyed, the matcher resource would also be freed in group dereference stage. The `group` information should be saved locally to get rid of the UAF issue in both stages. Coverity issue: 426423 Fixes: b2845d51c748 ("net/mlx5: support FDB in non-template flow") Signed-off-by: Maayan Kashani <mkash...@nvidia.com> Signed-off-by: Bing Zhao <bi...@nvidia.com> Acked-by: Dariusz Sosnowski <dsosnow...@nvidia.com> --- drivers/net/mlx5/mlx5_flow_hw.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index d243b59b71..470919fe8a 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -13471,22 +13471,16 @@ static int flow_hw_unregister_matcher(struct rte_eth_dev *dev, struct mlx5_flow_dv_matcher *matcher) { - int ret; struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_flow_group *group = matcher->group; + int ret = 0; - if (matcher->matcher_object) { - ret = mlx5_hlist_unregister(priv->sh->groups, &matcher->group->entry); - if (ret) - goto error; - if (matcher->group) { - ret = mlx5_list_unregister(matcher->group->matchers, &matcher->entry); - if (ret) - goto error; - } + if (group) { + if (matcher->matcher_object) + ret |= mlx5_list_unregister(group->matchers, &matcher->entry); + ret |= mlx5_hlist_unregister(priv->sh->groups, &group->entry); } - return 0; -error: - return -EINVAL; + return ret; } static int flow_hw_register_matcher(struct rte_eth_dev *dev, -- 2.34.1