From: Roy Marples Date: Thu, 20 Aug 2020 15:28:47 +0000 (+0100) Subject: privsep: Only the master process accepts signals X-Git-Tag: v9.2.0~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d18b2a25e2e95595ff7b643d2a2754540549e3d;p=thirdparty%2Fdhcpcd.git privsep: Only the master process accepts signals The master process dictates when processes should stop, which allows for a clean shutdown when the admin issues `pkill dhcpcd`. --- diff --git a/src/eloop.c b/src/eloop.c index d43dbe83..16bb9b2a 100644 --- a/src/eloop.c +++ b/src/eloop.c @@ -703,9 +703,10 @@ eloop_start(struct eloop *eloop, sigset_t *signals) if (eloop->exitnow) break; - if (_eloop_nsig != 0 && eloop->signal_cb != NULL) { + if (_eloop_nsig != 0) { n = _eloop_sig[--_eloop_nsig]; - eloop->signal_cb(n, eloop->signal_cb_ctx); + if (eloop->signal_cb != NULL) + eloop->signal_cb(n, eloop->signal_cb_ctx); continue; } diff --git a/src/privsep-bpf.c b/src/privsep-bpf.c index 6892bf2a..3025fda8 100644 --- a/src/privsep-bpf.c +++ b/src/privsep-bpf.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -170,17 +169,6 @@ ps_bpf_start_bpf(void *arg) return -1; } -static void -ps_bpf_signal_bpfcb(int sig, void *arg) -{ - struct dhcpcd_ctx *ctx = arg; - - if (sig != SIGTERM) - return; - - eloop_exit(ctx->eloop, EXIT_SUCCESS); -} - ssize_t ps_bpf_cmd(struct dhcpcd_ctx *ctx, struct ps_msghdr *psm, struct msghdr *msg) { @@ -249,7 +237,7 @@ ps_bpf_cmd(struct dhcpcd_ctx *ctx, struct ps_msghdr *psm, struct msghdr *msg) start = ps_dostart(ctx, &psp->psp_pid, &psp->psp_fd, ps_bpf_recvmsg, NULL, psp, - ps_bpf_start_bpf, ps_bpf_signal_bpfcb, + ps_bpf_start_bpf, NULL, PSF_DROPPRIVS); switch (start) { case -1: diff --git a/src/privsep-control.c b/src/privsep-control.c index 306ab58f..e0f9088f 100644 --- a/src/privsep-control.c +++ b/src/privsep-control.c @@ -27,7 +27,6 @@ */ #include -#include #include #include @@ -95,18 +94,6 @@ ps_ctl_recvmsg(void *arg) logerr(__func__); } -static void -ps_ctl_signalcb(int sig, void *arg) -{ - struct dhcpcd_ctx *ctx = arg; - - if (sig != SIGTERM) - return; - - shutdown(ctx->ps_control_fd, SHUT_RDWR); - eloop_exit(ctx->eloop, EXIT_SUCCESS); -} - ssize_t ps_ctl_handleargs(struct fd_list *fd, char *data, size_t len) { @@ -251,7 +238,7 @@ ps_ctl_start(struct dhcpcd_ctx *ctx) pid = ps_dostart(ctx, &ctx->ps_control_pid, &ctx->ps_control_fd, ps_ctl_recvmsg, ps_ctl_dodispatch, ctx, - ps_ctl_startcb, ps_ctl_signalcb, + ps_ctl_startcb, NULL, PSF_DROPPRIVS); if (pid == -1) diff --git a/src/privsep-inet.c b/src/privsep-inet.c index 8bc0c2ea..89ba79e0 100644 --- a/src/privsep-inet.c +++ b/src/privsep-inet.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include @@ -291,18 +290,6 @@ ps_inet_recvmsg(void *arg) logerr(__func__); } -static void -ps_inet_signalcb(int sig, void *arg) -{ - struct dhcpcd_ctx *ctx = arg; - - if (sig != SIGTERM) - return; - - shutdown(ctx->ps_inet_fd, SHUT_RDWR); - eloop_exit(ctx->eloop, EXIT_SUCCESS); -} - ssize_t ps_inet_dispatch(void *arg, struct ps_msghdr *psm, struct msghdr *msg) { @@ -347,7 +334,7 @@ ps_inet_start(struct dhcpcd_ctx *ctx) pid = ps_dostart(ctx, &ctx->ps_inet_pid, &ctx->ps_inet_fd, ps_inet_recvmsg, ps_inet_dodispatch, ctx, - ps_inet_startcb, ps_inet_signalcb, + ps_inet_startcb, NULL, PSF_DROPPRIVS); #ifdef HAVE_CAPSICUM @@ -576,7 +563,7 @@ ps_inet_cmd(struct dhcpcd_ctx *ctx, struct ps_msghdr *psm, struct msghdr *msg) start = ps_dostart(ctx, &psp->psp_pid, &psp->psp_fd, ps_inet_recvmsgpsp, NULL, psp, - start_func, ps_inet_signalcb, + start_func, NULL, PSF_DROPPRIVS); switch (start) { case -1: diff --git a/src/privsep-root.c b/src/privsep-root.c index 3e2046ad..1a438b67 100644 --- a/src/privsep-root.c +++ b/src/privsep-root.c @@ -693,22 +693,14 @@ ps_root_startcb(void *arg) } static void -ps_root_signalcb(int sig, void *arg) +ps_root_signalcb(int sig, __unused void *arg) { - struct dhcpcd_ctx *ctx = arg; if (sig == SIGCHLD) { while (waitpid(-1, NULL, WNOHANG) > 0) ; return; } - - if (sig != SIGTERM) - return; - - shutdown(ctx->ps_root_fd, SHUT_RDWR); - shutdown(ctx->ps_data_fd, SHUT_RDWR); - eloop_exit(ctx->eloop, EXIT_SUCCESS); } int (*handle_interface)(void *, int, const char *); diff --git a/src/privsep.c b/src/privsep.c index c5e89baf..aa5cd9ab 100644 --- a/src/privsep.c +++ b/src/privsep.c @@ -34,6 +34,7 @@ * Spawn an unpriv process to send/receive common network data. * Then drop all privs and start running. * Every process aside from the privileged actioneer is chrooted. + * All privsep processes ignore signals - only the master process accepts them. * * dhcpcd will maintain the config file in the chroot, no need to handle * this in a script or something.