summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net-misc/dhcpcd/dhcpcd-10.0.5-r1.ebuild158
-rw-r--r--net-misc/dhcpcd/files/10.0.5/0001-control-fix-hangup-non-privsep-builds.patch23
-rw-r--r--net-misc/dhcpcd/files/10.0.5/0002-dhcpcd-detach-from-launcher.patch69
-rw-r--r--net-misc/dhcpcd/files/10.0.5/0003-control-abort-control-recv-path-hangup.patch105
-rw-r--r--net-misc/dhcpcd/files/10.0.5/0004-dhcpcd-remove-stdio-callback-detach-daemonize.patch286
-rw-r--r--net-misc/dhcpcd/files/10.0.5/0005-fix-privsep-builds-for-prior.patch20
-rw-r--r--net-misc/dhcpcd/files/10.0.5/0006-fix-unused-var-warning.patch37
7 files changed, 698 insertions, 0 deletions
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 <roy@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 <roy@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 <roy@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 <roy@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 <roy@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 <roy@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;
+