From: Olivier Houchard Date: Tue, 30 Sep 2025 13:16:44 +0000 (+0200) Subject: BUG/MEDIUM: stick-tables: Make sure not to free a pending entry X-Git-Tag: v3.3-dev9~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=21ae35dd299b2b09a8ed5cb75a61fe3e2e89b013;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: stick-tables: Make sure not to free a pending entry There is a race condition, an entry can be free'd by stksess_kill() between the time stktable_add_pend_updates() gets the entry from the mt_list, and the time it adds it to the ebtree. To prevent this, use the newly implemented MT_LIST_POP_LOCKED() to keep the stksess locked until it is added to the tree. That way, __stksess_kill() will wait until we're done with it. This should be backported to 3.2. --- diff --git a/src/stick_table.c b/src/stick_table.c index a7f16b5ba..9a0809cb3 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -811,7 +811,7 @@ struct task *stktable_add_pend_updates(struct task *t, void *ctx, unsigned int s goto leave; for (i = 0; i < STKTABLE_MAX_UPDATES_AT_ONCE; i++) { - struct stksess *stksess = MT_LIST_POP(&table->pend_updts[cur_tgid], typeof(stksess), pend_updts); + struct stksess *stksess = MT_LIST_POP_LOCKED(&table->pend_updts[cur_tgid], typeof(stksess), pend_updts); if (!stksess) { empty_tgid++; @@ -848,6 +848,13 @@ struct task *stktable_add_pend_updates(struct task *t, void *ctx, unsigned int s eb32_delete(eb); eb32_insert(&table->updates, &stksess->upd); } + /* + * Now that we're done inserting the stksess, unlock it. + * It is kept locked here to prevent a race condition + * when stksess_kill() could free() it after we removed + * it from the list, but before we inserted it into the tree + */ + MT_LIST_INIT(&stksess->pend_updts); } HA_RWLOCK_WRUNLOCK(STK_TABLE_UPDT_LOCK, &table->updt_lock);