summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-08-20 16:28:47 +0100
committerRoy Marples <roy@marples.name>2020-08-20 16:28:47 +0100
commit2d18b2a25e2e95595ff7b643d2a2754540549e3d (patch)
tree736348035fa69ab8f98a919aedd8185728fcd659
parent684895a84c40b4484c7e0d7ce555f7154d8e6d22 (diff)
downloaddhcpcd-2d18b2a25e2e95595ff7b643d2a2754540549e3d.tar.xz
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`.
-rw-r--r--src/eloop.c5
-rw-r--r--src/privsep-bpf.c14
-rw-r--r--src/privsep-control.c15
-rw-r--r--src/privsep-inet.c17
-rw-r--r--src/privsep-root.c10
-rw-r--r--src/privsep.c1
6 files changed, 9 insertions, 53 deletions
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 <assert.h>
#include <pwd.h>
#include <errno.h>
-#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -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 <errno.h>
-#include <signal.h>
#include <stdlib.h>
#include <string.h>
@@ -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 <assert.h>
#include <errno.h>
-#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -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.