From: Willy Tarreau Date: Sun, 5 Nov 2017 10:04:47 +0000 (+0100) Subject: BUG/MEDIUM: threads/stick-tables: close a race condition on stktable_trash_expired() X-Git-Tag: v1.8-rc3~61 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4d5f13cab3411cae504d579c4011a6707f133580;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: threads/stick-tables: close a race condition on stktable_trash_expired() The spin_unlock() was called just before setting the expiry to TICK_ETERNITY, so if another thread has the time to perform its update and set a timeout, this would would clear it. --- diff --git a/src/stick_table.c b/src/stick_table.c index 0e84102f6c..4810c7fcd2 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -536,8 +536,7 @@ static int stktable_trash_expired(struct stktable *t) if (likely(tick_is_lt(now_ms, eb->key))) { /* timer not expired yet, revisit it later */ t->exp_next = eb->key; - SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock); - return t->exp_next; + goto out_unlock; } /* timer looks expired, detach it from the queue */ @@ -567,10 +566,11 @@ static int stktable_trash_expired(struct stktable *t) eb32_delete(&ts->upd); __stksess_free(t, ts); } - SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock); /* We have found no task to expire in any tree */ t->exp_next = TICK_ETERNITY; +out_unlock: + SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock); return t->exp_next; }