Commit ac7f071673 for strongswan.org

commit ac7f071673568ebf049cbb194a3f1a5856afc882
Author: Tobias Brunner <tobias@strongswan.org>
Date:   Mon Jul 13 18:25:48 2026 +0200

    child-sa-manager: Correctly remove replaced entry in lookup tables

    In the (very) unlikely case that a unique ID is reused (e.g. due to
    counter wraparound) while the original SA is still in this manager,
    the entries should properly get removed from the other lookup tables
    before the entry is destroyed to prevent stale pointers from getting
    used in later lookups.

    Fixes: e732fb11a915 ("child-sa-manager: Add a global manager storing CHILD_SA relations")

diff --git a/src/libcharon/sa/child_sa_manager.c b/src/libcharon/sa/child_sa_manager.c
index 31c27014e9..042d3c21bc 100644
--- a/src/libcharon/sa/child_sa_manager.c
+++ b/src/libcharon/sa/child_sa_manager.c
@@ -143,7 +143,7 @@ static bool equals_id(child_entry_t *a, child_entry_t *b)
 METHOD(child_sa_manager_t, add, void,
 	private_child_sa_manager_t *this, child_sa_t *child_sa, ike_sa_t *ike_sa)
 {
-	child_entry_t *entry;
+	child_entry_t *entry, *replaced;
 	host_t *in, *out;
 	ike_sa_id_t *id;

@@ -165,9 +165,16 @@ METHOD(child_sa_manager_t, add, void,
 	if (!this->in->get(this->in, entry) &&
 		!this->out->get(this->out, entry))
 	{
+		replaced = this->ids->put(this->ids, entry, entry);
+		if (replaced)
+		{	/* remove the replaced entry in the other tables in case the unique
+			 * ID got reused */
+			this->in->remove(this->in, replaced);
+			this->out->remove(this->out, replaced);
+		}
 		this->in->put(this->in, entry, entry);
 		this->out->put(this->out, entry, entry);
-		entry = this->ids->put(this->ids, entry, entry);
+		entry = replaced;
 	}
 	this->mutex->unlock(this->mutex);