]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: sockpair: set FD_CLOEXEC on fd received via SCM_RIGHTS
authorWilliam Lallemand <wlallemand@haproxy.com>
Mon, 16 Mar 2026 15:08:45 +0000 (16:08 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Mon, 16 Mar 2026 15:31:58 +0000 (16:31 +0100)
FDs received through recv_fd_uxst() do not have FD_CLOEXEC set.
The equivalent sock_accept_conn() already handles this correctly:
any FD accepted or received in the master must be marked close-on-exec
to avoid leaking it across the execvp() performed on soft-reload.

This is currently triggering a leak in the master since 3.1: the worker
sends a socketpair fd to the master  to issue the _send_status CLI
command, and recv_fd_uxst() receive it without setting FD_CLOEXEC.  If a
re-exec is emitted before the master had the chance to close that fd, it
survives execvp() and appears as an untracked unnamed AF_UNIX socket in
the new master generation.

This must be backported to all maintained branches.

src/proto_sockpair.c

index da39c5e9ed1f4151c5ffa81071feaacf4a22c868..840cd401043beed80855fce39c43f29ea51ada76 100644 (file)
@@ -488,8 +488,11 @@ struct connection *sockpair_accept_conn(struct listener *l, int *status)
        int ret;
        int cfd;
 
-       if ((cfd = recv_fd_uxst(l->rx.fd)) != -1)
+       if ((cfd = recv_fd_uxst(l->rx.fd)) != -1) {
                fd_set_nonblock(cfd);
+               if (master)
+                       fd_set_cloexec(cfd);
+       }
 
        if (likely(cfd != -1)) {
                /* Perfect, the connection was accepted */