From: Christopher Faulet Date: Fri, 22 Apr 2022 15:56:24 +0000 (+0200) Subject: BUG/MAJOR: connection: Never remove connection from idle lists outside the lock X-Git-Tag: v2.6-dev7~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7ae48a70d6f2de0a6d2b4426bdb2a129baffc579;p=thirdparty%2Fhaproxy.git BUG/MAJOR: connection: Never remove connection from idle lists outside the lock Since the idle connections management changed to use eb-trees instead of MT lists, a lock must be acquired to manipulate servers idle/safe/available connection lists. However, it remains an unprotected use in connect_server(), when a connection is removed from an idle list if the mux has no more streams available. Thus it is possible to remove a connection from an idle list on a thread, while another one is looking for a idle connection. Of couse, this may lead to a crash. To fix the bug, we must take care to acquire the idle connections lock first. The bug was introduced by the commit f232cb3e9 ("MEDIUM: connection: replace idle conn lists by eb trees"). The patch must be backported as far as 2.4. --- diff --git a/src/backend.c b/src/backend.c index 6bff6ffe5d..18c84f4e9b 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1529,7 +1529,9 @@ static int connect_server(struct stream *s) if (avail <= 1) { /* No more streams available, remove it from the list */ + HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); conn_delete_from_tree(&srv_conn->hash_node->node); + HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); } if (avail >= 1) {