From: Willy Tarreau Date: Tue, 21 Apr 2009 00:17:45 +0000 (+0200) Subject: [MEDIUM] ensure we don't recursively call pool_gc2() X-Git-Tag: v1.3.18~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7f9d126e269f3b5b7dc05e39fcf207ba86a330c;p=thirdparty%2Fhaproxy.git [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. --- 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--; } /*