From: Christopher Faulet Date: Thu, 23 May 2024 09:14:41 +0000 (+0200) Subject: BUG/MEDIUM: stick-tables: Fix race with peers when killing a sticky session X-Git-Tag: v3.0-dev13~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9938fb9c7a5b62d9c78b9c60caba744b6191fd1d;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: stick-tables: Fix race with peers when killing a sticky session When a sticky session is killed, we must be sure no other entity is still referencing it. The session's ref_cnt must be 0. However, there is a race with peers, as decribed in 21447b1dd4 ("BUG/MAJOR: stick-tables: fix race with peers in entry expiration"). When the update lock is acquire, we must recheck the ref_cnt value. This patch is part of a debugging session about issue #2552. It must be backported to 2.9. --- diff --git a/src/stick_table.c b/src/stick_table.c index 0d353e2e38..98afbe8736 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -141,17 +141,25 @@ void stksess_free(struct stktable *t, struct stksess *ts) */ int __stksess_kill(struct stktable *t, struct stksess *ts) { + int updt_locked = 0; + if (HA_ATOMIC_LOAD(&ts->ref_cnt)) return 0; - eb32_delete(&ts->exp); if (ts->upd.node.leaf_p) { + updt_locked = 1; HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->updt_lock); - eb32_delete(&ts->upd); - HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->updt_lock); + if (HA_ATOMIC_LOAD(&ts->ref_cnt)) + goto out_unlock; } + eb32_delete(&ts->exp); + eb32_delete(&ts->upd); ebmb_delete(&ts->key); __stksess_free(t, ts); + + out_unlock: + if (updt_locked) + HA_RWLOCK_WRUNLOCK(STK_TABLE_LOCK, &t->updt_lock); return 1; }