This diff fixes the same problem ntpd(8) had with the dup2() when oldd == newd.
Quick background: when you dup2(oldd, newd) and oldd == newd the CLOEXEC flag won't be removed by the descriptor. We could use dup3() to detect this, but it is easier/faster just to compare the fds and do the fcntl() ourselves. ok? Index: proc.c =================================================================== RCS file: /home/obsdcvs/src/usr.sbin/httpd/proc.c,v retrieving revision 1.27 diff -u -p -r1.27 proc.c --- proc.c 28 Sep 2016 12:01:04 -0000 1.27 +++ proc.c 5 Oct 2016 16:50:40 -0000 @@ -22,6 +22,7 @@ #include <sys/socket.h> #include <sys/wait.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -131,7 +132,12 @@ proc_exec(struct privsep *ps, struct pri break; case 0: /* Prepare parent socket. */ - dup2(fd, PROC_PARENT_SOCK_FILENO); + if (fd != PROC_PARENT_SOCK_FILENO) { + if (dup2(fd, PROC_PARENT_SOCK_FILENO) + == -1) + fatal("dup2"); + } else if (fcntl(fd, F_SETFD, 0) == -1) + fatal("fcntl"); execvp(argv[0], nargv); fatal("%s: execvp", __func__);