From b7f9d126e269f3b5b7dc05e39fcf207ba86a330c Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 21 Apr 2009 02:17:45 +0200 Subject: [PATCH] [MEDIUM] ensure we don't recursively call pool_gc2() A race condition exists in the hot reconfiguration code. It is theorically possible that the second signal is sent during a free() in the first list, which can cause crashes or freezes (the later have been observed). Just set up a counter to ensure we do not recurse. --- src/memory.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/memory.c b/src/memory.c index 05178e58ca..36db92e34e 100644 --- a/src/memory.c +++ b/src/memory.c @@ -122,11 +122,17 @@ void pool_flush2(struct pool_head *pool) /* * This function frees whatever can be freed in all pools, but respecting - * the minimum thresholds imposed by owners. + * the minimum thresholds imposed by owners. It takes care of avoiding + * recursion because it may be called from a signal handler. */ void pool_gc2() { + static int recurse; struct pool_head *entry; + + if (recurse++) + goto out; + list_for_each_entry(entry, &pools, list) { void *temp, *next; //qfprintf(stderr, "Flushing pool %s\n", entry->name); @@ -141,6 +147,8 @@ void pool_gc2() } entry->free_list = next; } + out: + recurse--; } /* -- 2.47.2