From 51d9339d04fb53c63a3f55c9cea2f4a63e6facbe Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Thu, 12 Mar 2020 19:05:39 +0100 Subject: [PATCH] BUG/MEDIUM: pools: Always update free_list in pool_gc(). In pool_gc(), when we're not using lockless pool, always update free_list, and read from it the next element to free. As we now unlock the pool while we're freeing the item, another thread could have updated free_list in our back. Not doing so could lead to segfaults when pool_gc() is called. This should be backported to 2.1. --- src/memory.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/memory.c b/src/memory.c index 0ff3ea8b8..b0512aaec 100644 --- a/src/memory.c +++ b/src/memory.c @@ -429,15 +429,14 @@ void pool_gc(struct pool_head *pool_ctx) return; list_for_each_entry(entry, &pools, list) { - void *temp, *next; + void *temp; //qfprintf(stderr, "Flushing pool %s\n", entry->name); if (entry != pool_ctx) HA_SPIN_LOCK(POOL_LOCK, &entry->lock); - next = entry->free_list; - while (next && + while (entry->free_list && (int)(entry->allocated - entry->used) > (int)entry->minavail) { - temp = next; - next = *POOL_LINK(entry, temp); + temp = entry->free_list; + entry->free_list = *POOL_LINK(entry, temp); entry->allocated--; if (entry != pool_ctx) HA_SPIN_UNLOCK(POOL_LOCK, &entry->lock); @@ -445,7 +444,6 @@ void pool_gc(struct pool_head *pool_ctx) if (entry != pool_ctx) HA_SPIN_LOCK(POOL_LOCK, &entry->lock); } - entry->free_list = next; if (entry != pool_ctx) HA_SPIN_UNLOCK(POOL_LOCK, &entry->lock); }