git: 2851aafe96c1 - main - mlx5 ipsec_offload: ensure that driver does not dereference dead sahindex

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Thu, 10 Oct 2024 10:00:07 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=2851aafe96c1e357971f2b331fff837ead20522b

commit 2851aafe96c1e357971f2b331fff837ead20522b
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-09-28 23:17:05 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-10-10 09:55:45 +0000

    mlx5 ipsec_offload: ensure that driver does not dereference dead sahindex
    
    Take the sahtree rlock and check for the DEAD SA state before validating
    and filling the SA xfrm attributes.
    
    Sponsored by:   NVidia networking
---
 sys/dev/mlx5/mlx5_accel/mlx5_ipsec.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/sys/dev/mlx5/mlx5_accel/mlx5_ipsec.c b/sys/dev/mlx5/mlx5_accel/mlx5_ipsec.c
index a25ed4c1c51f..95afec40d4f6 100644
--- a/sys/dev/mlx5/mlx5_accel/mlx5_ipsec.c
+++ b/sys/dev/mlx5/mlx5_accel/mlx5_ipsec.c
@@ -34,6 +34,7 @@
 #include <net/if.h>
 #include <net/if_var.h>
 #include <net/pfkeyv2.h>
+#include <netipsec/key.h>
 #include <netipsec/key_var.h>
 #include <netipsec/keydb.h>
 #include <netipsec/ipsec.h>
@@ -257,6 +258,8 @@ static int mlx5e_xfrm_validate_state(struct mlx5_core_dev *mdev,
 		mlx5_core_err(mdev, "FULL offload is not supported\n");
 		return (EINVAL);
 	}
+	if (savp->state == SADB_SASTATE_DEAD)
+		return (EINVAL);
 	if (savp->alg_enc == SADB_EALG_NONE) {
 		mlx5_core_err(mdev, "Cannot offload authenticated xfrm states\n");
 		return (EINVAL);
@@ -325,6 +328,7 @@ mlx5e_if_sa_newkey_onedir(struct ifnet *ifp, void *sav, int dir, u_int drv_spi,
     struct mlx5e_ipsec_sa_entry **privp, struct mlx5e_ipsec_priv_bothdir *pb,
     struct ifnet *ifpo)
 {
+	struct rm_priotracker tracker;
 	struct mlx5e_ipsec_sa_entry *sa_entry = NULL;
 	struct mlx5e_priv *priv = if_getsoftc(ifp);
 	struct mlx5_core_dev *mdev = priv->mdev;
@@ -338,7 +342,9 @@ mlx5e_if_sa_newkey_onedir(struct ifnet *ifp, void *sav, int dir, u_int drv_spi,
 	if (if_gettype(ifpo) == IFT_L2VLAN)
 		VLAN_TAG(ifpo, &vid);
 
+	ipsec_sahtree_rlock(&tracker);
 	err = mlx5e_xfrm_validate_state(mdev, sav);
+	ipsec_sahtree_runlock(&tracker);
 	if (err)
 		return err;
 
@@ -353,7 +359,14 @@ mlx5e_if_sa_newkey_onedir(struct ifnet *ifp, void *sav, int dir, u_int drv_spi,
 	sa_entry->ipsec = ipsec;
 	sa_entry->vid = vid;
 
+	ipsec_sahtree_rlock(&tracker);
+	err = mlx5e_xfrm_validate_state(mdev, sav);
+	if (err != 0) {
+		ipsec_sahtree_runlock(&tracker);
+		goto err_xfrm;
+	}
 	mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &sa_entry->attrs, dir);
+	ipsec_sahtree_runlock(&tracker);
 
 	err = mlx5e_ipsec_create_dwork(sa_entry, pb);
 	if (err)