mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-12-14 14:11:00 +01:00
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.
This commit is contained in:
parent
cf26745857
commit
21ae35dd29
@ -811,7 +811,7 @@ struct task *stktable_add_pend_updates(struct task *t, void *ctx, unsigned int s
|
|||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
for (i = 0; i < STKTABLE_MAX_UPDATES_AT_ONCE; i++) {
|
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) {
|
if (!stksess) {
|
||||||
empty_tgid++;
|
empty_tgid++;
|
||||||
@ -848,6 +848,13 @@ struct task *stktable_add_pend_updates(struct task *t, void *ctx, unsigned int s
|
|||||||
eb32_delete(eb);
|
eb32_delete(eb);
|
||||||
eb32_insert(&table->updates, &stksess->upd);
|
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);
|
HA_RWLOCK_WRUNLOCK(STK_TABLE_UPDT_LOCK, &table->updt_lock);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user