From ac7f071673568ebf049cbb194a3f1a5856afc882 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 13 Jul 2026 18:25:48 +0200 Subject: [PATCH] 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") --- src/libcharon/sa/child_sa_manager.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libcharon/sa/child_sa_manager.c b/src/libcharon/sa/child_sa_manager.c index 31c27014e..042d3c21b 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);