From: William Lallemand Date: Tue, 27 Nov 2018 11:02:39 +0000 (+0100) Subject: BUG/MEDIUM: listeners: CLOEXEC flag is not correctly set X-Git-Tag: v1.9-dev9~121 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d913800a7d680fdd7e7864463d5fa936b9d58fa8;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: listeners: CLOEXEC flag is not correctly set The CLOEXEC flag was set using a F_SETFL which can't work. To set the CLOEXEC flag F_SETFD should be used, the problem is that it needs a new call to fcntl() and it's on the path of every accept. This flag was only needed in the case of the master, so the patch was reverted and the flag set only in this case. The bug was introduced by 0b3e849 ("MEDIUM: listeners: set O_CLOEXEC on the accepted FDs"). No backport needed. --- diff --git a/src/listener.c b/src/listener.c index c75f8ef719..37466d44ec 100644 --- a/src/listener.c +++ b/src/listener.c @@ -544,7 +544,7 @@ void listener_accept(int fd) /* with sockpair@ we don't want to do an accept */ if (unlikely(l->addr.ss_family == AF_CUST_SOCKPAIR)) { if ((cfd = recv_fd_uxst(fd)) != -1) - fcntl(cfd, F_SETFL, O_NONBLOCK|O_CLOEXEC); + fcntl(cfd, F_SETFL, O_NONBLOCK); } else #ifdef USE_ACCEPT4 @@ -552,12 +552,12 @@ void listener_accept(int fd) * fallback to the legacy accept() + fcntl(). */ if (unlikely(accept4_broken || - ((cfd = accept4(fd, (struct sockaddr *)&addr, &laddr, SOCK_NONBLOCK|SOCK_CLOEXEC)) == -1 && + ((cfd = accept4(fd, (struct sockaddr *)&addr, &laddr, SOCK_NONBLOCK)) == -1 && (errno == ENOSYS || errno == EINVAL || errno == EBADF) && (accept4_broken = 1)))) #endif if ((cfd = accept(fd, (struct sockaddr *)&addr, &laddr)) != -1) - fcntl(cfd, F_SETFL, O_NONBLOCK|O_CLOEXEC); + fcntl(cfd, F_SETFL, O_NONBLOCK); if (unlikely(cfd == -1)) { switch (errno) { @@ -604,6 +604,10 @@ void listener_accept(int fd) } } + /* we don't want to leak the FD upon reload if it's in the master */ + if (unlikely(master == 1)) + fcntl(cfd, F_SETFD, FD_CLOEXEC); + if (unlikely(cfd >= global.maxsock)) { send_log(p, LOG_EMERG, "Proxy %s reached the configured maximum connection limit. Please check the global 'maxconn' value.\n",