From 3f44ca223a810815c425accc64949b25261cc96d Mon Sep 17 00:00:00 2001 From: Jorik Cronenberg Date: Mon, 14 Sep 2026 13:23:07 +0200 Subject: [PATCH 1/2] privsep: Fix daemonising broken by RLIMIT_NOFILE of 0 RLIMIT_NOFILE of 0 makes dup2(2) fail EBADF on linux, so daemonising could no longer redirect stdout/stderr to /dev/null and readers of a piped stdio never saw EOF. Cap at STDERR_FILENO + 1; as 0-2 are always open, no new fd can be allocated. --- src/privsep.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/privsep.c b/src/privsep.c index f35502e0..1cab3ce9 100644 --- a/src/privsep.c +++ b/src/privsep.c @@ -159,10 +159,18 @@ ps_dropprivs(struct dhcpcd_ctx *ctx) struct rlimit rzero = { .rlim_cur = 0, .rlim_max = 0 }; #ifndef __sun /* RLIMIT_NOFILE and ppoll don't mix */ +#ifdef __linux__ + /* Linux dup2(2) fails EBADF if RLIMIT_NOFILE is 0 */ + struct rlimit rnofile = { .rlim_cur = STDERR_FILENO + 1, + .rlim_max = STDERR_FILENO + 1 }; +#else + struct rlimit rnofile = { .rlim_cur = 0, .rlim_max = 0 }; +#endif + /* Prohibit new files, sockets, etc * The control proxy *does* need to create new fd's via accept(2). */ if (ctx->ps_ctl == NULL || ctx->ps_ctl->psp_pid != getpid()) { - if (setrlimit(RLIMIT_NOFILE, &rzero) == -1) + if (setrlimit(RLIMIT_NOFILE, &rnofile) == -1) logerr("setrlimit RLIMIT_NOFILE"); } #endif From fdfca357e2058a1ea696897cd0179ccd5370366b Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Sat, 10 Oct 2026 07:39:38 +0100 Subject: [PATCH 2/2] dhcpcd: warn on dup2 failures when daemonising --- src/dhcpcd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dhcpcd.c b/src/dhcpcd.c index bf277bbc..8d1f3a9d 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -340,8 +340,10 @@ dhcpcd_daemonised(struct dhcpcd_ctx *ctx) * We know that stdin is already mapped to /dev/null. * TODO: Capture script output and log it to the logfile and/or syslog. */ - dup2(STDIN_FILENO, STDOUT_FILENO); - dup2(STDIN_FILENO, STDERR_FILENO); + if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1) + logwarn("%s: dup2 %d", __func__, STDOUT_FILENO); + if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) + logwarn("%s: dup2 %d", __func__, STDERR_FILENO); ctx->options |= DHCPCD_DAEMONISED; } @@ -2040,7 +2042,7 @@ dup_null(int fd) } if ((err = dup2(fd_null, fd)) == -1) - logwarn("dup2 %d", fd); + logwarn("%s: dup2 %d", __func__, fd); close(fd_null); return err; }