]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: connection: Never remove connection from idle lists outside the lock
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 22 Apr 2022 15:56:24 +0000 (17:56 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 22 Apr 2022 16:16:06 +0000 (18:16 +0200)
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.

src/backend.c

index 6bff6ffe5d3908d01bfef452f6aeff5aa280a29f..18c84f4e9b467dba946dc0255c0057ea0355e9be 100644 (file)
@@ -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) {