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.
This commit is contained in:
Christopher Faulet 2025-11-14 11:31:45 +01:00
parent bf639e581d
commit bd4fff9a76

View File

@ -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;
}