From: Willy Tarreau Date: Wed, 15 Mar 2017 11:47:46 +0000 (+0100) Subject: BUG/MEDIUM: listener: do not try to rebind another process' socket X-Git-Tag: v1.8-dev1~78 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3569df3fcf770d6785b32a39c0ff0c3d2a180f44;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: listener: do not try to rebind another process' socket When the "process" setting of a bind line limits the processes a listening socket is enabled on, a "disable frontend" operation followed by an "enable frontend" triggers a bug because all declared listeners are attempted to be bound again regardless of their assigned processes. This can at minima create new sockets not receiving traffic, and at worst prevent from re-enabling a frontend if it's bound to a privileged port. This bug was introduced by commit 1c4b814 ("MEDIUM: listener: support rebinding during resume()") merged in 1.6-dev1, trying to perform the bind() before checking the process list instead of after. Just move the process check before the bind() operation to fix this. This fix must be backported to 1.7 and 1.6. Thanks to Pavlos for reporting this one. --- diff --git a/src/listener.c b/src/listener.c index 6b6b5d84c5..5f349110f0 100644 --- a/src/listener.c +++ b/src/listener.c @@ -128,6 +128,11 @@ int pause_listener(struct listener *l) */ int resume_listener(struct listener *l) { + if ((global.mode & (MODE_DAEMON | MODE_SYSTEMD)) && + l->bind_conf->bind_proc && + !(l->bind_conf->bind_proc & (1UL << (relative_pid - 1)))) + return 1; + if (l->state == LI_ASSIGNED) { char msg[100]; int err; @@ -145,11 +150,6 @@ int resume_listener(struct listener *l) if (l->state < LI_PAUSED) return 0; - if ((global.mode & (MODE_DAEMON | MODE_SYSTEMD)) && - l->bind_conf->bind_proc && - !(l->bind_conf->bind_proc & (1UL << (relative_pid - 1)))) - return 1; - if (l->proto->sock_prot == IPPROTO_TCP && l->state == LI_PAUSED && listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)