]> www.infradead.org Git - users/hch/misc.git/commitdiff
net/mlx5e: Skip restore TC rules for vport rep without loaded flag
authorJianbo Liu <jianbol@nvidia.com>
Fri, 20 Dec 2024 08:15:04 +0000 (10:15 +0200)
committerJakub Kicinski <kuba@kernel.org>
Mon, 23 Dec 2024 18:54:02 +0000 (10:54 -0800)
During driver unload, unregister_netdev is called after unloading
vport rep. So, the mlx5e_rep_priv is already freed while trying to get
rpriv->netdev, or walk rpriv->tc_ht, which results in use-after-free.
So add the checking to make sure access the data of vport rep which is
still loaded.

Fixes: d1569537a837 ("net/mlx5e: Modify and restore TC rules for IPSec TX rules")
Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20241220081505.1286093-4-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c

index 5a0047bdcb5105ae4992578003007d21dd4fa1b5..ed977ae75fab8983e1f9c7b6334dfd0939ef5151 100644 (file)
@@ -150,11 +150,11 @@ void mlx5_esw_ipsec_restore_dest_uplink(struct mlx5_core_dev *mdev)
        unsigned long i;
        int err;
 
-       xa_for_each(&esw->offloads.vport_reps, i, rep) {
-               rpriv = rep->rep_data[REP_ETH].priv;
-               if (!rpriv || !rpriv->netdev)
+       mlx5_esw_for_each_rep(esw, i, rep) {
+               if (atomic_read(&rep->rep_data[REP_ETH].state) != REP_LOADED)
                        continue;
 
+               rpriv = rep->rep_data[REP_ETH].priv;
                rhashtable_walk_enter(&rpriv->tc_ht, &iter);
                rhashtable_walk_start(&iter);
                while ((flow = rhashtable_walk_next(&iter)) != NULL) {
index a83d41121db67123b5ce18683f0262cbf7416e80..8573d36785f426fdf7e4c6c2ac53d0baf078baaa 100644 (file)
@@ -714,6 +714,9 @@ void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw);
                          MLX5_CAP_GEN_2((esw->dev), ec_vf_vport_base) +\
                          (last) - 1)
 
+#define mlx5_esw_for_each_rep(esw, i, rep) \
+       xa_for_each(&((esw)->offloads.vport_reps), i, rep)
+
 struct mlx5_eswitch *__must_check
 mlx5_devlink_eswitch_get(struct devlink *devlink);
 
index d5b42b3a19fdf776060e679edb8c714f165e1c4d..40359f32072487238c8b77fbd49c876d468e8394 100644 (file)
@@ -53,9 +53,6 @@
 #include "lag/lag.h"
 #include "en/tc/post_meter.h"
 
-#define mlx5_esw_for_each_rep(esw, i, rep) \
-       xa_for_each(&((esw)->offloads.vport_reps), i, rep)
-
 /* There are two match-all miss flows, one for unicast dst mac and
  * one for multicast.
  */