commit:     67d10729f24850c81361c37a81e41c1640db2b93
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Mon Nov 13 22:03:14 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Nov 13 22:03:14 2023 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=67d10729

net-misc/dhcpcd: backport fork/daemonize fixes

Bug: https://github.com/NetworkConfiguration/dhcpcd/issues/262
Signed-off-by: Sam James <sam <AT> gentoo.org>

 net-misc/dhcpcd/dhcpcd-10.0.5-r1.ebuild            | 158 ++++++++++++
 ...001-control-fix-hangup-non-privsep-builds.patch |  23 ++
 .../10.0.5/0002-dhcpcd-detach-from-launcher.patch  |  69 +++++
 ...03-control-abort-control-recv-path-hangup.patch | 105 ++++++++
 ...cd-remove-stdio-callback-detach-daemonize.patch | 286 +++++++++++++++++++++
 .../10.0.5/0005-fix-privsep-builds-for-prior.patch |  20 ++
 .../files/10.0.5/0006-fix-unused-var-warning.patch |  37 +++
 7 files changed, 698 insertions(+)

diff --git a/net-misc/dhcpcd/dhcpcd-10.0.5-r1.ebuild 
b/net-misc/dhcpcd/dhcpcd-10.0.5-r1.ebuild
new file mode 100644
index 000000000000..437899bb6d47
--- /dev/null
+++ b/net-misc/dhcpcd/dhcpcd-10.0.5-r1.ebuild
@@ -0,0 +1,158 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit systemd toolchain-funcs
+
+if [[ ${PV} == 9999 ]]; then
+       inherit git-r3
+       EGIT_REPO_URI="https://github.com/NetworkConfiguration/dhcpcd.git";
+else
+       MY_P="${P/_alpha/-alpha}"
+       MY_P="${MY_P/_beta/-beta}"
+       MY_P="${MY_P/_rc/-rc}"
+       
SRC_URI="https://github.com/NetworkConfiguration/dhcpcd/releases/download/v${PV}/${MY_P}.tar.xz";
+       S="${WORKDIR}/${MY_P}"
+
+       KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~loong ~m68k ~mips ~ppc 
~ppc64 ~riscv ~s390 ~sparc ~x86 ~amd64-linux ~x86-linux"
+fi
+
+DESCRIPTION="A fully featured, yet light weight RFC2131 compliant DHCP client"
+HOMEPAGE="https://github.com/NetworkConfiguration/dhcpcd/ 
https://roy.marples.name/projects/dhcpcd/";
+
+LICENSE="BSD-2 BSD ISC MIT"
+SLOT="0"
+IUSE="debug +embedded ipv6 privsep +udev"
+
+DEPEND="udev? ( virtual/udev )"
+RDEPEND="
+       ${DEPEND}
+       privsep? (
+               acct-group/dhcpcd
+               acct-user/dhcpcd
+       )
+"
+
+PATCHES=(
+       "${FILESDIR}"/10.0.5
+)
+
+src_configure() {
+       local myeconfargs=(
+               --dbdir="${EPREFIX}/var/lib/dhcpcd"
+               --libexecdir="${EPREFIX}/lib/dhcpcd"
+               --localstatedir="${EPREFIX}/var"
+               --prefix="${EPREFIX}"
+               --with-hook=ntp.conf
+               $(use_enable debug)
+               $(use_enable embedded)
+               $(use_enable ipv6)
+               $(use_enable privsep)
+               $(usex elibc_glibc '--with-hook=yp.conf' '')
+               --rundir=$(usex kernel_linux "${EPREFIX}/run/dhcpcd" 
"${EPREFIX}/var/run/dhcpcd")
+               $(usex privsep '--privsepuser=dhcpcd' '')
+               $(usex udev '' '--without-dev --without-udev')
+               CC="$(tc-getCC)"
+       )
+       econf "${myeconfargs[@]}"
+}
+
+src_install() {
+       default
+       keepdir /var/lib/dhcpcd
+       newinitd "${FILESDIR}"/dhcpcd.initd-r1 dhcpcd
+       systemd_newunit "${FILESDIR}"/dhcpcd.service-r1 dhcpcd.service
+}
+
+pkg_postinst() {
+       local dbdir="${EROOT}"/var/lib/dhcpcd old_files=()
+
+       local old_old_duid="${EROOT}"/var/lib/dhcpcd/dhcpcd.duid
+       local old_duid="${EROOT}"/etc/dhcpcd.duid
+       local new_duid="${dbdir}"/duid
+       if [[ -e "${old_old_duid}" ]] ; then
+               # Upgrade the duid file to the new format if needed
+               if ! grep -q '..:..:..:..:..:..' "${old_old_duid}"; then
+                       sed -i -e 's/\(..\)/\1:/g; s/:$//g' "${old_old_duid}"
+               fi
+
+               # Move the duid to /etc, a more sensible location
+               if [[ ! -e "${old_duid}" ]] ; then
+                       cp -p "${old_old_duid}" "${new_duid}"
+               fi
+               old_files+=( "${old_old_duid}" )
+       fi
+
+       # dhcpcd-7 moves the files out of /etc
+       if [[ -e "${old_duid}" ]] ; then
+               if [[ ! -e "${new_duid}" ]] ; then
+                       cp -p "${old_duid}" "${new_duid}"
+               fi
+               old_files+=( "${old_duid}" )
+       fi
+       local old_secret="${EROOT}"/etc/dhcpcd.secret
+       local new_secret="${dbdir}"/secret
+       if [[ -e "${old_secret}" ]] ; then
+               if [[ ! -e "${new_secret}" ]] ; then
+                       cp -p "${old_secret}" "${new_secret}"
+               fi
+               old_files+=( "${old_secret}" )
+       fi
+
+       # dhcpcd-7 renames some files in /var/lib/dhcpcd
+       local old_rdm="${dbdir}"/dhcpcd-rdm.monotonic
+       local new_rdm="${dbdir}"/rdm_monotonic
+       if [[ -e "${old_rdm}" ]] ; then
+               if [[ ! -e "${new_rdm}" ]] ; then
+                       cp -p "${old_rdm}" "${new_rdm}"
+               fi
+               old_files+=( "${old_rdm}" )
+       fi
+       local lease=
+       for lease in "${dbdir}"/dhcpcd-*.lease*; do
+               [[ -f "${lease}" ]] || continue
+               old_files+=( "${lease}" )
+               local new_lease=$(basename "${lease}" | sed -e "s/dhcpcd-//")
+               [[ -e "${dbdir}/${new_lease}" ]] && continue
+               cp "${lease}" "${dbdir}/${new_lease}"
+       done
+
+       # Warn about removing stale files
+       if [[ -n "${old_files[@]}" ]] ; then
+               elog
+               elog "dhcpcd-7 has copied dhcpcd.duid and dhcpcd.secret from"
+               elog "${EROOT}/etc to ${dbdir}"
+               elog "and copied leases in ${dbdir} to new files with the 
dhcpcd-"
+               elog "prefix dropped."
+               elog
+               elog "You should remove these files if you don't plan on 
reverting"
+               elog "to an older version:"
+               local old_file=
+               for old_file in ${old_files[@]}; do
+                       elog "  ${old_file}"
+               done
+       fi
+
+       if [ -z "${REPLACING_VERSIONS}" ]; then
+               elog
+               elog "dhcpcd has zeroconf support active by default."
+               elog "This means it will always obtain an IP address even if no"
+               elog "DHCP server can be contacted, which will break any 
existing"
+               elog "failover support you may have configured in your net 
configuration."
+               elog "This behaviour can be controlled with the noipv4ll 
configuration"
+               elog "file option or the -L command line switch."
+               elog "See the dhcpcd and dhcpcd.conf man pages for more 
details."
+
+               elog
+               elog "Dhcpcd has duid enabled by default, and this may cause 
issues"
+               elog "with some dhcp servers. For more information, see"
+               elog "https://bugs.gentoo.org/show_bug.cgi?id=477356";
+       fi
+
+       if ! has_version net-dns/bind-tools; then
+               elog
+               elog "If you activate the lookup-hostname hook to look up your 
hostname"
+               elog "using the dns, you need to install net-dns/bind-tools."
+       fi
+}

diff --git 
a/net-misc/dhcpcd/files/10.0.5/0001-control-fix-hangup-non-privsep-builds.patch 
b/net-misc/dhcpcd/files/10.0.5/0001-control-fix-hangup-non-privsep-builds.patch
new file mode 100644
index 000000000000..632cf402fc94
--- /dev/null
+++ 
b/net-misc/dhcpcd/files/10.0.5/0001-control-fix-hangup-non-privsep-builds.patch
@@ -0,0 +1,23 @@
+https://github.com/NetworkConfiguration/dhcpcd/issues/262
+https://github.com/NetworkConfiguration/dhcpcd/commit/584b52db330a96471ff9301b85ce47ebb065a8a4
+
+From 584b52db330a96471ff9301b85ce47ebb065a8a4 Mon Sep 17 00:00:00 2001
+From: Roy Marples <r...@marples.name>
+Date: Sun, 12 Nov 2023 11:30:01 +0000
+Subject: [PATCH] control: Fix hangup for non privsep builds
+
+Fix related to #262.
+--- a/src/control.c
++++ b/src/control.c
+@@ -113,8 +113,9 @@ control_handle_read(struct fd_list *fd)
+       ssize_t bytes;
+ 
+       bytes = read(fd->fd, buffer, sizeof(buffer) - 1);
+-      if (bytes == -1) {
++      if (bytes == -1)
+               logerr(__func__);
++      if (bytes == -1 || bytes == 0) {
+               control_hangup(fd);
+               return;
+       }
+

diff --git 
a/net-misc/dhcpcd/files/10.0.5/0002-dhcpcd-detach-from-launcher.patch 
b/net-misc/dhcpcd/files/10.0.5/0002-dhcpcd-detach-from-launcher.patch
new file mode 100644
index 000000000000..44de6a83f843
--- /dev/null
+++ b/net-misc/dhcpcd/files/10.0.5/0002-dhcpcd-detach-from-launcher.patch
@@ -0,0 +1,69 @@
+https://github.com/NetworkConfiguration/dhcpcd/issues/262
+https://github.com/NetworkConfiguration/dhcpcd/commit/21d020b00e60e71b1300d89815f914145d7372f6
+
+From 21d020b00e60e71b1300d89815f914145d7372f6 Mon Sep 17 00:00:00 2001
+From: Roy Marples <r...@marples.name>
+Date: Sun, 12 Nov 2023 12:16:53 +0000
+Subject: [PATCH] dhcpcd: Detach from launcher before stopping root process
+
+This fixes non privsep builds where the launcher reports dhcpcd
+hungup. Unsure why this happens, but it should not be a problem.
+
+While here, shutdown has no effect on non STREAM sockets and
+remove the silly error logging in fork_cb that we read an
+error. We already printed the error so this makes no sense.
+
+Hopefully fixes #262.
+--- a/src/dhcpcd.c
++++ b/src/dhcpcd.c
+@@ -395,7 +395,6 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
+               logerr("write");
+       ctx->options |= DHCPCD_DAEMONISED;
+       // dhcpcd_fork_cb will close the socket
+-      shutdown(ctx->fork_fd, SHUT_RDWR);
+ #endif
+ }
+ 
+@@ -1877,8 +1876,6 @@ dhcpcd_fork_cb(void *arg, unsigned short events)
+       if (ctx->options & DHCPCD_FORKED) {
+               if (exit_code == EXIT_SUCCESS)
+                       logdebugx("forked to background");
+-              else
+-                      logerrx("exited with code %d", exit_code);
+               eloop_exit(ctx->eloop, exit_code);
+       } else
+               dhcpcd_signal_cb(exit_code, ctx);
+@@ -2738,8 +2735,19 @@ main(int argc, char **argv, char **envp)
+       if (ps_stopwait(&ctx) != EXIT_SUCCESS)
+               i = EXIT_FAILURE;
+ #endif
+-      if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED))
++      if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED)) {
+               loginfox(PACKAGE " exited");
++#ifdef USE_SIGNALS
++              /* Detach from the launch process.
++               * This *should* happen after we stop the root process,
++               * but for some reason non privsep builds get a zero length
++               * read in dhcpcd_fork_cb(). */
++              if (ctx.fork_fd != -1) {
++                      if (write(ctx.fork_fd, &i, sizeof(i)) == -1)
++                              logerr("%s: write", __func__);
++              }
++#endif
++      }
+ #ifdef PRIVSEP
+       if (ps_root_stop(&ctx) == -1)
+               i = EXIT_FAILURE;
+@@ -2753,12 +2761,6 @@ main(int argc, char **argv, char **envp)
+       setproctitle_fini();
+ #endif
+ #ifdef USE_SIGNALS
+-      if (ctx.options & DHCPCD_STARTED) {
+-              /* Try to detach from the launch process. */
+-              if (ctx.fork_fd != -1 &&
+-                  write(ctx.fork_fd, &i, sizeof(i)) == -1)
+-                      logerr("%s: write", __func__);
+-      }
+       if (ctx.options & (DHCPCD_FORKED | DHCPCD_PRIVSEP))
+               _exit(i); /* so atexit won't remove our pidfile */
+ #endif

diff --git 
a/net-misc/dhcpcd/files/10.0.5/0003-control-abort-control-recv-path-hangup.patch
 
b/net-misc/dhcpcd/files/10.0.5/0003-control-abort-control-recv-path-hangup.patch
new file mode 100644
index 000000000000..de4ee353ccf3
--- /dev/null
+++ 
b/net-misc/dhcpcd/files/10.0.5/0003-control-abort-control-recv-path-hangup.patch
@@ -0,0 +1,105 @@
+https://github.com/NetworkConfiguration/dhcpcd/issues/262
+https://github.com/NetworkConfiguration/dhcpcd/commit/3b4c71859c45b9405f96a5ee8fce04bd3014b2d0
+
+From 3b4c71859c45b9405f96a5ee8fce04bd3014b2d0 Mon Sep 17 00:00:00 2001
+From: Roy Marples <r...@marples.name>
+Date: Mon, 13 Nov 2023 10:24:15 +0000
+Subject: [PATCH] control: Abort control recv path on hangup
+
+This fixes a crash when we try and re-use it in another function.
+--- a/src/control.c
++++ b/src/control.c
+@@ -106,7 +106,7 @@ control_hangup(struct fd_list *fd)
+       control_free(fd);
+ }
+ 
+-static void
++static int
+ control_handle_read(struct fd_list *fd)
+ {
+       char buffer[1024];
+@@ -117,7 +117,7 @@ control_handle_read(struct fd_list *fd)
+               logerr(__func__);
+       if (bytes == -1 || bytes == 0) {
+               control_hangup(fd);
+-              return;
++              return -1;
+       }
+ 
+ #ifdef PRIVSEP
+@@ -129,21 +129,23 @@ control_handle_read(struct fd_list *fd)
+               fd->flags &= ~FD_SENDLEN;
+               if (err == -1) {
+                       logerr(__func__);
+-                      return;
++                      return 0;
+               }
+               if (err == 1 &&
+                   ps_ctl_sendargs(fd, buffer, (size_t)bytes) == -1) {
+                       logerr(__func__);
+                       control_free(fd);
++                      return -1;
+               }
+-              return;
++              return 0;
+       }
+ #endif
+ 
+       control_recvdata(fd, buffer, (size_t)bytes);
++      return 0;
+ }
+ 
+-static void
++static int
+ control_handle_write(struct fd_list *fd)
+ {
+       struct iovec iov[2];
+@@ -170,7 +172,7 @@ control_handle_write(struct fd_list *fd)
+                       logerr("%s: write", __func__);
+               }
+               control_hangup(fd);
+-              return;
++              return -1;
+       }
+ 
+       TAILQ_REMOVE(&fd->queue, data, next);
+@@ -183,7 +185,7 @@ control_handle_write(struct fd_list *fd)
+ #endif
+ 
+       if (TAILQ_FIRST(&fd->queue) != NULL)
+-              return;
++              return 0;
+ 
+ #ifdef PRIVSEP
+       if (IN_PRIVSEP_SE(fd->ctx) && !(fd->flags & FD_LISTEN)) {
+@@ -196,9 +198,9 @@ control_handle_write(struct fd_list *fd)
+       if (eloop_event_add(fd->ctx->eloop, fd->fd, ELE_READ,
+           control_handle_data, fd) == -1)
+               logerr("%s: eloop_event_add", __func__);
++      return 0;
+ }
+ 
+-
+ static void
+ control_handle_data(void *arg, unsigned short events)
+ {
+@@ -207,10 +209,14 @@ control_handle_data(void *arg, unsigned short events)
+       if (!(events & (ELE_READ | ELE_WRITE | ELE_HANGUP)))
+               logerrx("%s: unexpected event 0x%04x", __func__, events);
+ 
+-      if (events & ELE_WRITE && !(events & ELE_HANGUP))
+-              control_handle_write(fd);
+-      if (events & ELE_READ)
+-              control_handle_read(fd);
++      if (events & ELE_WRITE && !(events & ELE_HANGUP)) {
++              if (control_handle_write(fd) == -1)
++                      return;
++      }
++      if (events & ELE_READ) {
++              if (control_handle_read(fd) == -1)
++                      return;
++      }
+       if (events & ELE_HANGUP)
+               control_hangup(fd);
+ }
+

diff --git 
a/net-misc/dhcpcd/files/10.0.5/0004-dhcpcd-remove-stdio-callback-detach-daemonize.patch
 
b/net-misc/dhcpcd/files/10.0.5/0004-dhcpcd-remove-stdio-callback-detach-daemonize.patch
new file mode 100644
index 000000000000..331f60e739a1
--- /dev/null
+++ 
b/net-misc/dhcpcd/files/10.0.5/0004-dhcpcd-remove-stdio-callback-detach-daemonize.patch
@@ -0,0 +1,286 @@
+https://github.com/NetworkConfiguration/dhcpcd/issues/262
+https://github.com/NetworkConfiguration/dhcpcd/commit/ea53344a2430736124bf9fa62acb0d3107acd58f
+
+From ea53344a2430736124bf9fa62acb0d3107acd58f Mon Sep 17 00:00:00 2001
+From: Roy Marples <r...@marples.name>
+Date: Mon, 13 Nov 2023 10:29:58 +0000
+Subject: [PATCH] dhcpcd: Remove stdio callback and detach on daemonise
+
+For some reason, the stdio callback is extremely flaky on
+*some* Linux based distributions making it very hard to debug some
+things.
+Removing it is fine because we now enforce that we have file descriptors
+for stdin, stdout and stdrr on launch and dup them to /dev/null on daemonise.
+
+It's also interesting to see behavioural differences between
+some socketpair implementations that emit a HANGUP and some don't.
+
+As such, we now close the fork socket on daemonise once more AND
+in the fork_cb depending on if we hangup or read zero first.
+
+Fixes #262
+--- a/src/dhcpcd.c
++++ b/src/dhcpcd.c
+@@ -364,7 +364,7 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
+       errno = ENOSYS;
+       return;
+ #else
+-      int i;
++      int exit_code;
+ 
+       if (ctx->options & DHCPCD_DAEMONISE &&
+           !(ctx->options & (DHCPCD_DAEMONISED | DHCPCD_NOWAITIP)))
+@@ -385,16 +385,19 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
+               return;
+ 
+ #ifdef PRIVSEP
+-      ps_daemonised(ctx);
++      if (IN_PRIVSEP(ctx))
++              ps_daemonised(ctx);
++      else
+ #else
+-      dhcpcd_daemonised(ctx);
++              dhcpcd_daemonised(ctx);
+ #endif
+ 
+-      i = EXIT_SUCCESS;
+-      if (write(ctx->fork_fd, &i, sizeof(i)) == -1)
+-              logerr("write");
+-      ctx->options |= DHCPCD_DAEMONISED;
+-      // dhcpcd_fork_cb will close the socket
++      eloop_event_delete(ctx->eloop, ctx->fork_fd);
++      exit_code = EXIT_SUCCESS;
++      if (write(ctx->fork_fd, &exit_code, sizeof(exit_code)) == -1)
++              logerr(__func__);
++      close(ctx->fork_fd);
++      ctx->fork_fd = -1;
+ #endif
+ }
+ 
+@@ -1814,30 +1817,6 @@ dhcpcd_readdump(struct dhcpcd_ctx *ctx)
+           dhcpcd_readdump0, ctx);
+ }
+ 
+-static void
+-dhcpcd_stderr_cb(void *arg, unsigned short events)
+-{
+-      struct dhcpcd_ctx *ctx = arg;
+-      char log[BUFSIZ];
+-      ssize_t len;
+-
+-      if (events & ELE_HANGUP)
+-              eloop_exit(ctx->eloop, EXIT_SUCCESS);
+-
+-      if (!(events & ELE_READ))
+-              return;
+-
+-      len = read(ctx->stderr_fd, log, sizeof(log) - 1);
+-      if (len == -1) {
+-              if (errno != ECONNRESET)
+-                      logerr(__func__);
+-              return;
+-      }
+-
+-      log[len] = '\0';
+-      fprintf(stderr, "%s", log);
+-}
+-
+ static void
+ dhcpcd_fork_cb(void *arg, unsigned short events)
+ {
+@@ -1928,7 +1907,7 @@ main(int argc, char **argv, char **envp)
+       ssize_t len;
+ #if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK)
+       pid_t pid;
+-      int fork_fd[2], stderr_fd[2];
++      int fork_fd[2];
+ #endif
+ #ifdef USE_SIGNALS
+       int sig = 0;
+@@ -2013,22 +1992,17 @@ main(int argc, char **argv, char **envp)
+       TAILQ_INIT(&ctx.ps_processes);
+ #endif
+ 
+-      /* Check our streams for validity */
+-      ctx.stdin_valid =  fcntl(STDIN_FILENO,  F_GETFD) != -1;
+-      ctx.stdout_valid = fcntl(STDOUT_FILENO, F_GETFD) != -1;
+-      ctx.stderr_valid = fcntl(STDERR_FILENO, F_GETFD) != -1;
++      logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID;
+ 
+-      /* Even we if we don't have input/outputs, we need to
+-       * ensure they are setup for shells. */
+-      if (!ctx.stdin_valid)
++      /* Ensure we have stdin, stdout and stderr file descriptors.
++       * This is important as we do run scripts which expect these. */
++      if (fcntl(STDIN_FILENO,  F_GETFD) == -1)
+               dup_null(STDIN_FILENO);
+-      if (!ctx.stdout_valid)
++      if (fcntl(STDOUT_FILENO,  F_GETFD) == -1)
+               dup_null(STDOUT_FILENO);
+-      if (!ctx.stderr_valid)
++      if (fcntl(STDERR_FILENO,  F_GETFD) == -1)
+               dup_null(STDERR_FILENO);
+-
+-      logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID;
+-      if (ctx.stderr_valid)
++      else
+               logopts |= LOGERR_ERR;
+ 
+       i = 0;
+@@ -2398,17 +2372,13 @@ main(int argc, char **argv, char **envp)
+       loginfox(PACKAGE "-" VERSION " starting");
+ 
+       // We don't need stdin past this point
+-      if (ctx.stdin_valid)
+-              dup_null(STDIN_FILENO);
++      dup_null(STDIN_FILENO);
+ 
+ #if defined(USE_SIGNALS) && !defined(THERE_IS_NO_FORK)
+       if (!(ctx.options & DHCPCD_DAEMONISE))
+               goto start_manager;
+ 
+-      if (xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, fork_fd) == -1 ||
+-          (ctx.stderr_valid &&
+-          xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, stderr_fd) == -1))
+-      {
++      if (xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, fork_fd) == -1) {
+               logerr("socketpair");
+               goto exit_failure;
+       }
+@@ -2429,22 +2399,6 @@ main(int argc, char **argv, char **envp)
+                   dhcpcd_fork_cb, &ctx) == -1)
+                       logerr("%s: eloop_event_add", __func__);
+ 
+-              /*
+-               * Redirect stderr to the stderr socketpair.
+-               * Redirect stdout as well.
+-               * dhcpcd doesn't output via stdout, but something in
+-               * a called script might.
+-               */
+-              if (ctx.stderr_valid) {
+-                      if (dup2(stderr_fd[1], STDERR_FILENO) == -1 ||
+-                          (ctx.stdout_valid &&
+-                          dup2(stderr_fd[1], STDOUT_FILENO) == -1))
+-                              logerr("dup2");
+-                      close(stderr_fd[0]);
+-                      close(stderr_fd[1]);
+-              } else if (ctx.stdout_valid)
+-                      dup_null(STDOUT_FILENO);
+-
+               if (setsid() == -1) {
+                       logerr("%s: setsid", __func__);
+                       goto exit_failure;
+@@ -2478,19 +2432,6 @@ main(int argc, char **argv, char **envp)
+                   dhcpcd_fork_cb, &ctx) == -1)
+                       logerr("%s: eloop_event_add", __func__);
+ 
+-              if (ctx.stderr_valid) {
+-                      ctx.stderr_fd = stderr_fd[0];
+-                      close(stderr_fd[1]);
+-#ifdef PRIVSEP_RIGHTS
+-                      if (ps_rights_limit_fd(ctx.stderr_fd) == 1) {
+-                              logerr("ps_rights_limit_fd");
+-                              goto exit_failure;
+-                      }
+-#endif
+-                      if (eloop_event_add(ctx.eloop, ctx.stderr_fd, ELE_READ,
+-                          dhcpcd_stderr_cb, &ctx) == -1)
+-                              logerr("%s: eloop_event_add", __func__);
+-              }
+ #ifdef PRIVSEP
+               if (IN_PRIVSEP(&ctx) && ps_managersandbox(&ctx, NULL) == -1)
+                       goto exit_failure;
+@@ -2602,6 +2543,7 @@ main(int argc, char **argv, char **envp)
+               if (ifp->active == IF_ACTIVE_USER)
+                       break;
+       }
++
+       if (ifp == NULL) {
+               if (ctx.ifc == 0) {
+                       int loglevel;
+@@ -2735,24 +2677,22 @@ main(int argc, char **argv, char **envp)
+       if (ps_stopwait(&ctx) != EXIT_SUCCESS)
+               i = EXIT_FAILURE;
+ #endif
+-      if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED)) {
++      if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED))
+               loginfox(PACKAGE " exited");
+-#ifdef USE_SIGNALS
+-              /* Detach from the launch process.
+-               * This *should* happen after we stop the root process,
+-               * but for some reason non privsep builds get a zero length
+-               * read in dhcpcd_fork_cb(). */
+-              if (ctx.fork_fd != -1) {
+-                      if (write(ctx.fork_fd, &i, sizeof(i)) == -1)
+-                              logerr("%s: write", __func__);
+-              }
+-#endif
+-      }
+ #ifdef PRIVSEP
+       if (ps_root_stop(&ctx) == -1)
+               i = EXIT_FAILURE;
+       eloop_free(ctx.ps_eloop);
+ #endif
++
++#ifdef USE_SIGNALS
++      /* If still attached, detach from the launcher */
++      if (ctx.options & DHCPCD_STARTED && ctx.fork_fd != -1) {
++              if (write(ctx.fork_fd, &i, sizeof(i)) == -1)
++                      logerr("%s: write", __func__);
++      }
++#endif
++
+       eloop_free(ctx.eloop);
+       logclose();
+       free(ctx.logfile);
+@@ -2760,6 +2700,7 @@ main(int argc, char **argv, char **envp)
+ #ifdef SETPROCTITLE_H
+       setproctitle_fini();
+ #endif
++
+ #ifdef USE_SIGNALS
+       if (ctx.options & (DHCPCD_FORKED | DHCPCD_PRIVSEP))
+               _exit(i); /* so atexit won't remove our pidfile */
+--- a/src/dhcpcd.h
++++ b/src/dhcpcd.h
+@@ -116,10 +116,6 @@ struct passwd;
+ struct dhcpcd_ctx {
+       char pidfile[sizeof(PIDFILE) + IF_NAMESIZE + 1];
+       char vendor[256];
+-      bool stdin_valid;       /* It's possible stdin, stdout and stderr */
+-      bool stdout_valid;      /* could be closed when dhcpcd starts. */
+-      bool stderr_valid;
+-      int stderr_fd;  /* FD for logging to stderr */
+       int fork_fd;    /* FD for the fork init signal pipe */
+       const char *cffile;
+       unsigned long long options;
+--- a/src/privsep.c
++++ b/src/privsep.c
+@@ -172,8 +172,7 @@ ps_dropprivs(struct dhcpcd_ctx *ctx)
+        * Obviously this won't work if we are using a logfile
+        * or redirecting stderr to a file. */
+       if ((ctx->options & DHC_NOCHKIO) == DHC_NOCHKIO ||
+-          (ctx->logfile == NULL &&
+-          (!ctx->stderr_valid || isatty(STDERR_FILENO) == 1)))
++          (ctx->logfile == NULL && isatty(STDERR_FILENO) == 1))
+       {
+               if (setrlimit(RLIMIT_FSIZE, &rzero) == -1)
+                       logerr("setrlimit RLIMIT_FSIZE");
+@@ -305,14 +304,11 @@ ps_rights_limit_stdio(struct dhcpcd_ctx *ctx)
+       const int iebadf = CAPH_IGNORE_EBADF;
+       int error = 0;
+ 
+-      if (ctx->stdin_valid &&
+-          caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1)
++      if (caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1)
+               error = -1;
+-      if (ctx->stdout_valid &&
+-          caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1)
++      if (caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1)
+               error = -1;
+-      if (ctx->stderr_valid &&
+-          caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1)
++      if (caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1)
+               error = -1;
+ 
+       return error;

diff --git 
a/net-misc/dhcpcd/files/10.0.5/0005-fix-privsep-builds-for-prior.patch 
b/net-misc/dhcpcd/files/10.0.5/0005-fix-privsep-builds-for-prior.patch
new file mode 100644
index 000000000000..bafabfcb0275
--- /dev/null
+++ b/net-misc/dhcpcd/files/10.0.5/0005-fix-privsep-builds-for-prior.patch
@@ -0,0 +1,20 @@
+https://github.com/NetworkConfiguration/dhcpcd/commit/8d12632c670f02d8a685e80c8abad7049d3dd18f
+
+From 8d12632c670f02d8a685e80c8abad7049d3dd18f Mon Sep 17 00:00:00 2001
+From: Roy Marples <r...@marples.name>
+Date: Mon, 13 Nov 2023 15:54:50 +0000
+Subject: [PATCH] Fix privsep builds for prior.
+
+--- a/src/dhcpcd.c
++++ b/src/dhcpcd.c
+@@ -388,9 +388,8 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
+       if (IN_PRIVSEP(ctx))
+               ps_daemonised(ctx);
+       else
+-#else
+-              dhcpcd_daemonised(ctx);
+ #endif
++              dhcpcd_daemonised(ctx);
+ 
+       eloop_event_delete(ctx->eloop, ctx->fork_fd);
+       exit_code = EXIT_SUCCESS;

diff --git a/net-misc/dhcpcd/files/10.0.5/0006-fix-unused-var-warning.patch 
b/net-misc/dhcpcd/files/10.0.5/0006-fix-unused-var-warning.patch
new file mode 100644
index 000000000000..9672dc5b9570
--- /dev/null
+++ b/net-misc/dhcpcd/files/10.0.5/0006-fix-unused-var-warning.patch
@@ -0,0 +1,37 @@
+https://github.com/NetworkConfiguration/dhcpcd/commit/6788608eb0fcd32fd23974100cdd42d3174cb8d1
+
+From 6788608eb0fcd32fd23974100cdd42d3174cb8d1 Mon Sep 17 00:00:00 2001
+From: Roy Marples <r...@marples.name>
+Date: Mon, 13 Nov 2023 16:05:04 +0000
+Subject: [PATCH] Fix an unused var warning for capsicum for prior
+
+--- a/src/privsep.c
++++ b/src/privsep.c
+@@ -299,7 +299,7 @@ ps_rights_limit_fdpair(int fd[])
+ }
+ 
+ static int
+-ps_rights_limit_stdio(struct dhcpcd_ctx *ctx)
++ps_rights_limit_stdio()
+ {
+       const int iebadf = CAPH_IGNORE_EBADF;
+       int error = 0;
+@@ -452,7 +452,7 @@ ps_startprocess(struct ps_process *psp,
+                       ctx->ps_log_root_fd = -1;
+               }
+ #ifdef PRIVSEP_RIGHTS
+-              if (ps_rights_limit_stdio(ctx) == -1) {
++              if (ps_rights_limit_stdio() == -1) {
+                       logerr("ps_rights_limit_stdio");
+                       goto errexit;
+               }
+@@ -666,7 +666,7 @@ ps_managersandbox(struct dhcpcd_ctx *ctx, const char 
*_pledge)
+ #ifdef PRIVSEP_RIGHTS
+       if ((ctx->pf_inet_fd != -1 &&
+           ps_rights_limit_ioctl(ctx->pf_inet_fd) == -1) ||
+-           ps_rights_limit_stdio(ctx) == -1)
++           ps_rights_limit_stdio() == -1)
+       {
+               logerr("%s: cap_rights_limit", __func__);
+               return -1;
+

Reply via email to