git: 1a56620b7958 - main - ipsec esp: avoid dereferencing freed secasindex

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 26 Feb 2024 14:28:04 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=1a56620b7958cac2b9048589cb730c46958ab539

commit 1a56620b7958cac2b9048589cb730c46958ab539
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-02-25 10:30:48 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-02-26 14:27:46 +0000

    ipsec esp: avoid dereferencing freed secasindex
    
    It is possible that SA was removed while processing packed, in which
    case it is changed to the DEAD state and it index is removed from the
    tree. Dereferencing sav->sah then touches freed memory.
    
    Reviewed by:    ae
    Sponsored by:   NVIDIA networking
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D44079
---
 sys/netipsec/xform_esp.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c
index 16f7b24375fa..7ad6085db87f 100644
--- a/sys/netipsec/xform_esp.c
+++ b/sys/netipsec/xform_esp.c
@@ -508,6 +508,13 @@ esp_input_cb(struct cryptop *crp)
 	xd = crp->crp_opaque;
 	CURVNET_SET(xd->vnet);
 	sav = xd->sav;
+	if (sav->state >= SADB_SASTATE_DEAD) {
+		/* saidx is freed */
+		DPRINTF(("%s: dead SA %p spi %#x\n", __func__, sav, sav->spi));
+		ESPSTAT_INC(esps_notdb);
+		error = ESRCH;
+		goto bad;
+	}
 	skip = xd->skip;
 	protoff = xd->protoff;
 	cryptoid = xd->cryptoid;