Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 167 additions & 89 deletions compat/pidfile.c

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions compat/pidfile.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
* Copyright (c) 1999, 2016 The NetBSD Foundation, Inc.
* Copyright (c) 1999, 2016, 2026 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
Expand Down Expand Up @@ -31,10 +31,18 @@
#ifndef PIDFILE_H
#define PIDFILE_H

#include <unistd.h>
#include <sys/types.h>

#include "config.h"

int pidfile(const char *);
int pidfile_clean(void);
pid_t pidfile_lock(const char *);
pid_t pidfile_read(const char *);
int pidfile_unlock(void);

int pidfile_fd(void);
const char * pidfile_path(void);
void pidfile_unremoveable(void);

#endif
7 changes: 4 additions & 3 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -1039,12 +1039,12 @@ elif [ "$PRIVSEP" = yes ]; then
fi

if [ -z "$PIDFILE_LOCK" ]; then
printf "Testing for pidfile_lock ... "
printf "Testing for pidfile_unlock ... "
cat <<EOF >_pidfile.c
#include <stdlib.h>
#include <util.h>
int main(void) {
return (int)pidfile_lock(NULL);
return (int)pidfile_unlock();
}
EOF
# We only want to link to libutil if it exists in /lib
Expand All @@ -1065,8 +1065,9 @@ EOF
rm -rf _pidfile.* _pidfile
fi
if [ "$PIDFILE_LOCK" = no ]; then
echo "COMPAT_SRCS+= compat/pidfile.c" >>$CONFIG_MK
echo "CPPFLAGS+= -DPIDFILE_LOCAL" >>$CONFIG_MK
echo "#include \"compat/pidfile.h\"" >>$CONFIG_H
echo "COMPAT_SRCS+= compat/pidfile.c" >>$CONFIG_MK
else
echo "#define HAVE_UTIL_H" >>$CONFIG_H
if [ -n "$LIBUTIL" ]; then
Expand Down
1 change: 1 addition & 0 deletions src/bpf-bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "bpf.h"
#ifdef __sun
Expand Down
1 change: 1 addition & 0 deletions src/bpf-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "bpf.h"

Expand Down
1 change: 1 addition & 0 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "common.h"
#include "dhcpcd.h"
Expand Down
29 changes: 21 additions & 8 deletions src/dhcpcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2289,11 +2289,15 @@ main(int argc, char **argv, char **envp)
default:
per = "";
}
snprintf(ctx.pidfile, sizeof(ctx.pidfile), PIDFILE,
ifname, per, ".");
if (asprintf(&ctx.pidfile, PIDFILE, ifname, per, ".") == -1) {
logerr("%s: asprintf", __func__);
goto exit_failure;
}
} else {
snprintf(ctx.pidfile, sizeof(ctx.pidfile), PIDFILE, "",
"", "");
if (asprintf(&ctx.pidfile, PIDFILE, "", "", "") == -1) {
logerr("%s: asprintf", __func__);
goto exit_failure;
}
ctx.options |= DHCPCD_MANAGER;

/*
Expand Down Expand Up @@ -2582,6 +2586,18 @@ main(int argc, char **argv, char **envp)
#endif
goto exit_failure;
}
#ifdef PRIVSEP_RIGHTS
{
cap_rights_t rights;

cap_rights_init(&rights, CAP_READ, CAP_SEEK, CAP_FTRUNCATE);
if (cap_rights_limit(pidfile_fd(), &rights) == -1 &&
errno != ENOSYS) {
logerr("%s: cap_rights_limit", __func__);
goto exit_failure;
}
}
#endif
#endif

os_init();
Expand Down Expand Up @@ -2817,6 +2833,7 @@ main(int argc, char **argv, char **envp)
}
#endif

free(ctx.pidfile);
eloop_free(ctx.eloop);
logclose();
free(ctx.logfile);
Expand All @@ -2826,9 +2843,5 @@ main(int argc, char **argv, char **envp)
setproctitle_fini();
#endif

#ifdef USE_SIGNALS
if (ctx.options & (DHCPCD_FORKED | DHCPCD_PRIVSEP))
_exit(i); /* so atexit won't remove our pidfile */
#endif
return i;
}
2 changes: 1 addition & 1 deletion src/dhcpcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ TAILQ_HEAD(if_head, interface);
struct passwd;

struct dhcpcd_ctx {
char pidfile[sizeof(PIDFILE) + IF_NAMESIZE + 1];
char *pidfile;
char vendor[256];
int fork_fd; /* FD for the fork init signal pipe */
const char *cffile;
Expand Down
1 change: 1 addition & 0 deletions src/privsep-control.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "control.h"
#include "dhcpcd.h"
Expand Down
6 changes: 6 additions & 0 deletions src/privsep-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,9 @@ static struct sock_filter ps_seccomp_filter[] = {
#ifdef __NR_fstat64
SECCOMP_ALLOW(__NR_fstat64),
#endif
#ifdef __NR_ftruncate
SECCOMP_ALLOW(__NR_ftruncate),
#endif
#ifdef __NR_gettimeofday
SECCOMP_ALLOW(__NR_gettimeofday),
#endif
Expand Down Expand Up @@ -364,6 +367,9 @@ static struct sock_filter ps_seccomp_filter[] = {
/* SECCOMP BPF is newer than nl80211 so we don't need SIOCGIWESSID
* which lives in the impossible to include linux/wireless.h header */
#endif
#ifdef __NR_lseek
SECCOMP_ALLOW(__NR_lseek),
#endif
#ifdef __NR_madvise /* needed for musl */
SECCOMP_ALLOW(__NR_madvise),
#endif
Expand Down
9 changes: 7 additions & 2 deletions src/privsep.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,11 @@ ps_startprocess(struct ps_process *psp,
return pid;
}

/* If we are not the root process, close un-needed stuff. */
/* Close things we no longer need */
pidfile_unlock();
eloop_closefdwaiter(ctx->eloop);

/* Close more if we are not root */
if (ctx->ps_root != psp) {
ps_root_close(ctx);
#ifdef PLUGIN_DEV
Expand All @@ -420,7 +423,6 @@ ps_startprocess(struct ps_process *psp,
goto errexit;
}

pidfile_clean();
ps_freeprocesses(ctx, psp);

if (ctx->ps_root != psp) {
Expand Down Expand Up @@ -622,6 +624,9 @@ ps_managersandbox(struct dhcpcd_ctx *ctx, const char *_pledge)
return -1;
}

/* We can no longer unlink the pidfile. */
pidfile_unremoveable();

#ifdef PRIVSEP_RIGHTS
if ((ctx->pf_inet_fd != -1 &&
ps_rights_limit_ioctl(ctx->pf_inet_fd) == -1) ||
Expand Down