]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
privsep: Only the master process accepts signals
authorRoy Marples <roy@marples.name>
Thu, 20 Aug 2020 15:28:47 +0000 (16:28 +0100)
committerRoy Marples <roy@marples.name>
Thu, 20 Aug 2020 15:28:47 +0000 (16:28 +0100)
The master process dictates when processes should stop, which
allows for a clean shutdown when the admin issues `pkill dhcpcd`.

src/eloop.c
src/privsep-bpf.c
src/privsep-control.c
src/privsep-inet.c
src/privsep-root.c
src/privsep.c

index d43dbe8340ad9d6798d0036b37311fe49ab721ac..16bb9b2a9da70333338c979855f5b8a1bd542ec7 100644 (file)
@@ -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;
                }
 
index 6892bf2a6a822feace4e3831e750af99e93f46b1..3025fda8914a97a8c52e2f9405783ddf1eb0bd20 100644 (file)
@@ -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:
index 306ab58fa16998b13256bf3a3818c76d0b994881..e0f9088f59ee810e5fcefaa169a20a92c5ba74f4 100644 (file)
@@ -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)
index 8bc0c2eaf0a0f0d51a41eac94309c77ad3fce998..89ba79e039ae0ac434342ce22384c6b70dc590e7 100644 (file)
@@ -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:
index 3e2046ad5b49183faf3818e56e52e02def3a7f23..1a438b67d354c5b5d045c9999460bc0b33d88d64 100644 (file)
@@ -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 *);
index c5e89baf975965074cba069486bba49f2d7f3fd6..aa5cd9abc2070f00aed9c1fe65a16e00562f5405 100644 (file)
@@ -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.