From 4d5f13cab3411cae504d579c4011a6707f133580 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 5 Nov 2017 11:04:47 +0100 Subject: [PATCH] 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. --- src/stick_table.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stick_table.c b/src/stick_table.c index 0e84102f6..4810c7fcd 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; }