From 1c59bd5abc3db643617712c550e3b9383dbc22ea Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 2 Nov 2015 20:20:11 +0100 Subject: [PATCH] BUG/MAJOR: http: don't requeue an idle connection that is already queued MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cyril Bonté reported a reproduceable sequence which can lead to a crash when using backend connection reuse. The problem comes from the fact that we systematically add the server connection to an idle pool at the end of the HTTP transaction regardless of the fact that it might already be there. This is possible for example when processing a request which doesn't use a server connection (typically a redirect) after a request which used a connection. Then after the first request, the connection was already in the idle queue and we're putting it a second time at the end of the second request, causing a corruption of the idle pool. Interestingly, the memory debugger in 1.7 immediately detected a suspicious double free on the connection, leading to a very early detection of the cause instead of its consequences. Thanks to Cyril for quickly providing a working reproducer. This fix must be backported to 1.6 since connection reuse was introduced there. --- src/proto_http.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/proto_http.c b/src/proto_http.c index 32b9063a9..2dcac0674 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -5278,8 +5278,8 @@ void http_end_txn_clean_session(struct stream *s) channel_auto_read(&s->res); channel_auto_close(&s->res); - /* we're in keep-alive with an idle connection, monitor it */ - if (srv_conn) { + /* we're in keep-alive with an idle connection, monitor it if not already done */ + if (srv_conn && LIST_ISEMPTY(&srv_conn->list)) { srv = objt_server(srv_conn->target); if (!srv) si_idle_conn(&s->si[1], NULL);