Avoid calling flow_hw_unregister_matcher twice when rule creation
fails due to insufficient memory, which previously caused
a use-after-free error detected by ASan.

As a preventative measure, clear released pointers in
flow_hw_destroy to avoid potential double-free issues.

Fixes: b2845d51c748 ("net/mlx5: support FDB in non-template flow")
Cc: sta...@dpdk.org

Signed-off-by: Maayan Kashani <mkash...@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnow...@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow_hw.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 6dc16f80d32..062d2903a73 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -14082,11 +14082,6 @@ flow_hw_create_flow(struct rte_eth_dev *dev, enum 
mlx5_flow_type type,
                mlx5_free(hw_act.push_remove);
        if (hw_act.mhdr)
                mlx5_free(hw_act.mhdr);
-       if (ret) {
-               /* release after actual error */
-               if ((*flow)->nt2hws && (*flow)->nt2hws->matcher)
-                       flow_hw_unregister_matcher(dev, 
(*flow)->nt2hws->matcher);
-       }
        return ret;
 }
 #endif
@@ -14104,6 +14099,7 @@ flow_hw_destroy(struct rte_eth_dev *dev, struct 
rte_flow_hw *flow)
                ret = mlx5dr_bwc_rule_destroy(flow->nt2hws->nt_rule);
                if (ret)
                        DRV_LOG(ERR, "bwc rule destroy failed");
+               flow->nt2hws->nt_rule = NULL;
        }
        flow->operation_type = MLX5_FLOW_HW_FLOW_OP_TYPE_DESTROY;
        /* Notice this function does not handle shared/static actions. */
@@ -14118,18 +14114,24 @@ flow_hw_destroy(struct rte_eth_dev *dev, struct 
rte_flow_hw *flow)
          * Notice matcher destroy will take place when matcher's list is 
destroyed
          * , same as for DV.
          */
-       if (flow->nt2hws->flow_aux)
+       if (flow->nt2hws->flow_aux) {
                mlx5_free(flow->nt2hws->flow_aux);
-
-       if (flow->nt2hws->rix_encap_decap)
+               flow->nt2hws->flow_aux = NULL;
+       }
+       if (flow->nt2hws->rix_encap_decap) {
                flow_encap_decap_resource_release(dev, 
flow->nt2hws->rix_encap_decap);
+               flow->nt2hws->rix_encap_decap = 0;
+       }
        if (flow->nt2hws->modify_hdr) {
                MLX5_ASSERT(flow->nt2hws->modify_hdr->action);
                mlx5_hlist_unregister(priv->sh->modify_cmds,
                                      &flow->nt2hws->modify_hdr->entry);
+               flow->nt2hws->modify_hdr = NULL;
        }
-       if (flow->nt2hws->matcher)
+       if (flow->nt2hws->matcher) {
                flow_hw_unregister_matcher(dev, flow->nt2hws->matcher);
+               flow->nt2hws->matcher = NULL;
+       }
        if (flow->nt2hws->sample_release_ctx != NULL) {
                mlx5_nta_sample_mirror_entry_release(dev, 
flow->nt2hws->sample_release_ctx);
                flow->nt2hws->sample_release_ctx = NULL;
-- 
2.21.0

Reply via email to