From c03eb01c1ac478683b70a9b3fd776a8bf25e004d Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Tue, 27 Nov 2018 12:02:37 +0100 Subject: [PATCH] BUG/MEDIUM: mworker: avoid leak of client socket If the master was reloaded and there was a established connection to a server, the FD resulting from the accept was leaking. There was no CLOEXEC flag set on the FD of the socketpair created during a connect call. This is specific to the socketpair in the master process but it should be applied to every protocol in case we use them in the master at some point. No backport needed. --- src/proto_sockpair.c | 9 +++++++++ src/proto_tcp.c | 8 ++++++++ src/proto_uxst.c | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/src/proto_sockpair.c b/src/proto_sockpair.c index ef0e725639..f83c51b86c 100644 --- a/src/proto_sockpair.c +++ b/src/proto_sockpair.c @@ -280,6 +280,15 @@ static int sockpair_connect_server(struct connection *conn, int data, int delack return SF_ERR_INTERNAL; } + if (master == 1 && (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)) { + ha_alert("Cannot set CLOEXEC on client socket.\n"); + close(sv[0]); + close(sv[1]); + conn->err_code = CO_ER_SOCK_ERR; + conn->flags |= CO_FL_ERROR; + return SF_ERR_INTERNAL; + } + /* if a send_proxy is there, there are data */ data |= conn->send_proxy_ofs; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 0c531e6ec9..9bc048b9c8 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -364,6 +364,14 @@ int tcp_connect_server(struct connection *conn, int data, int delack) return SF_ERR_INTERNAL; } + if (master == 1 && (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)) { + ha_alert("Cannot set CLOEXEC on client socket.\n"); + close(fd); + conn->err_code = CO_ER_SOCK_ERR; + conn->flags |= CO_FL_ERROR; + return SF_ERR_INTERNAL; + } + if (be->options & PR_O_TCP_SRV_KA) setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)); diff --git a/src/proto_uxst.c b/src/proto_uxst.c index 878a10db59..965b7cb84f 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -502,6 +502,14 @@ static int uxst_connect_server(struct connection *conn, int data, int delack) return SF_ERR_INTERNAL; } + if (master == 1 && (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)) { + ha_alert("Cannot set CLOEXEC on client socket.\n"); + close(fd); + conn->err_code = CO_ER_SOCK_ERR; + conn->flags |= CO_FL_ERROR; + return SF_ERR_INTERNAL; + } + /* if a send_proxy is there, there are data */ data |= conn->send_proxy_ofs;