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.
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 */