BUG/MEDIUM: connections: Hold the lock when wanting to kill a connection.
authorOlivier Houchard <cognet@ci0.org>
Mon, 30 Dec 2019 17:15:40 +0000 (18:15 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 9 Jan 2020 16:40:55 +0000 (17:40 +0100)
In connect_server(), when we decide we want to kill the connection of
another thread because there are too many idle connections, hold the
toremove_lock of the corresponding thread, othervise, there's a small race
condition where we could try to add the connection to the toremove_connections
list while it has already been free'd.

This should be backported to 2.0 and 2.1.

(cherry picked from commit 140237471e408736bb7162e68c572c710a66a526)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

src/backend.c

index ebc5050..be081a5 100644 (file)
@@ -1295,6 +1295,7 @@ int connect_server(struct stream *s)
                                // see it possibly larger.
                                ALREADY_CHECKED(i);
 
+                               HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]);
                                tokill_conn = MT_LIST_POP(&srv->idle_orphan_conns[i],
                                    struct connection *, list);
                                if (tokill_conn) {
@@ -1305,6 +1306,7 @@ int connect_server(struct stream *s)
                                        task_wakeup(idle_conn_cleanup[i], TASK_WOKEN_OTHER);
                                        break;
                                }
+                               HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
                        }
                }