From bd4fff9a767945be278d84cc98dcbe2245652b59 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Fri, 14 Nov 2025 11:31:45 +0100 Subject: [PATCH] BUG/MEDIUM: stick-tables: Always return the good stksess from stktable_set_entry In stktable_set_entry(), the return value of __stktable_store() is not tested while it is possible to get an existing session with the same key instead of the one we want to insert. It happens when we fails to upgrade the read lock on the bucket to an write lock. In that case, we release the lock for a short time to get a write lock. So, to fix the bug, we must check the session returned by __stktable_store() and take care to return this one. The bug was introduced by the commit e62885237c ("MEDIUM: stick-table: make stktable_set_entry() look up under a read lock"). It must be backported as far as 2.8. --- src/stick_table.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/stick_table.c b/src/stick_table.c index c9faa56a8..240f10c75 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -927,10 +927,9 @@ struct stksess *stktable_set_entry(struct stktable *table, struct stksess *nts) HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &table->shards[shard].sh_lock); return ts; } - ts = nts; /* let's increment it before switching to exclusive */ - HA_ATOMIC_INC(&ts->ref_cnt); + HA_ATOMIC_INC(&nts->ref_cnt); if (HA_RWLOCK_TRYRDTOSK(STK_TABLE_LOCK, &table->shards[shard].sh_lock) != 0) { /* upgrade to seek lock failed, let's drop and take */ @@ -942,10 +941,15 @@ struct stksess *stktable_set_entry(struct stktable *table, struct stksess *nts) /* now we're write-locked */ - __stktable_store(table, ts, shard); + ts = __stktable_store(table, nts, shard); + if (ts != nts) { + HA_ATOMIC_DEC(&nts->ref_cnt); + HA_ATOMIC_INC(&ts->ref_cnt); + } HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &table->shards[shard].sh_lock); - stktable_requeue_exp(table, ts); + if (ts == nts) + stktable_requeue_exp(table, ts); return ts; }