From 902407bc588575af0ceae5de4f635fe1e024f258 Mon Sep 17 00:00:00 2001 From: Joas Antonio dos Santos Date: Tue, 27 Oct 2026 18:17:06 -0300 Subject: [PATCH] net/mlx5: macsec: free struct mlx5_fs_id after an RCU grace period macsec_fs_id_del() removes a struct mlx5_fs_id from its rhashtable with rhashtable_remove_fast() and then frees it with kfree() right away. The TX (SCI) table is read locklessly from the transmit path: mlx5e_macsec_handle_tx_skb() and mlx5e_macsec_tx_build_eseg() call mlx5_macsec_fs_get_fs_id_from_hashtable(), which does rhashtable_lookup() under rcu_read_lock() and then reads mlx5_fs_id->id. A transmit that looked the entry up just before it was removed reads freed memory. Before commit d4ece08f4b1d ("net/mlx5: Maintain fs_id xarray per MACsec device inside macsec steering") the SCI table held struct mlx5e_macsec_sa directly, and mlx5e_macsec_del_txsa() freed it with kfree_rcu_mightsleep(). That commit moved the table into macsec_fs.c with the new struct mlx5_fs_id, but frees it with a plain kfree(). Add an rcu_head to struct mlx5_fs_id and free it with kfree_rcu(). The same issue was flagged by the Sashiko AI review as a pre-existing problem while reviewing the HW-GRO for PSP series. Fixes: d4ece08f4b1d ("net/mlx5: Maintain fs_id xarray per MACsec device inside macsec steering") Link: https://lore.kernel.org/all/20260909065542.4B80D1F00ACA@smtp.kernel.org/ Signed-off-by: Joas Antonio dos Santos Assisted-by: Yaga Agent HackerSec Claude:claude-opus-5-5 Reviewed-by: Simon Horman Signed-off-by: Dave Miller --- drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c index efc5167493c1..7d785c937d43 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c @@ -94,6 +94,7 @@ struct mlx5_fs_id { refcount_t refcnt; sci_t sci; struct rhash_head hash; + struct rcu_head rcu; }; struct mlx5_macsec_device { @@ -684,7 +685,7 @@ static void macsec_fs_id_del(struct list_head *macsec_devices_list, u32 fs_id, xa_erase(fs_id_xa, fs_id); - kfree(fs_id_found); + kfree_rcu(fs_id_found, rcu); if (macsec_fs_is_macsec_device_empty(macsec_device)) { list_del(&macsec_device->macsec_devices_list_entry);