[2/4] net/mlx5: fix releasing order of compatible matcher

Message ID 20240723081522.1087433-3-bingz@nvidia.com (mailing list archive)
State Accepted, archived
Delegated to: Raslan Darawsheh
Headers
Series non-template fixes set |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Bing Zhao July 23, 2024, 8:15 a.m. UTC
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 <mkashani@nvidia.com>
Signed-off-by: Bing Zhao <bingz@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow_hw.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)
  

Patch

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,