summaryrefslogtreecommitdiffstats
path: root/src/privsep-root.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-06-02 15:50:17 +0100
committerRoy Marples <roy@marples.name>2020-06-02 15:50:17 +0100
commit828e858d3d7bbdb82bec7cd56616795426861783 (patch)
tree8a0b14e8f7c4ffca25bbd8654b68d93c99899dda /src/privsep-root.c
parent0a8158b5a0d6e8287c2127f96c95b7799abb3e23 (diff)
downloaddhcpcd-828e858d3d7bbdb82bec7cd56616795426861783.tar.xz
privsep: harden process handling
If eloop is exited, only allow explicit re-entry. Only exit on read/write error if a forked process and not root. If the root process fails to read/write to a sub-process, stop the sub-process.
Diffstat (limited to 'src/privsep-root.c')
-rw-r--r--src/privsep-root.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/privsep-root.c b/src/privsep-root.c
index 04e19742..4f963d31 100644
--- a/src/privsep-root.c
+++ b/src/privsep-root.c
@@ -124,6 +124,7 @@ ps_root_readerror(struct dhcpcd_ctx *ctx, void *data, size_t len)
ps_root_readerrorcb, &psr_ctx) == -1)
return -1;
+ eloop_enter(ctx->ps_eloop);
eloop_start(ctx->ps_eloop, &ctx->sigset);
errno = psr_ctx.psr_error.psr_errno;
@@ -181,6 +182,7 @@ ps_root_mreaderror(struct dhcpcd_ctx *ctx, void **data, size_t *len)
ps_root_mreaderrorcb, &psr_ctx) == -1)
return -1;
+ eloop_enter(ctx->ps_eloop);
eloop_start(ctx->ps_eloop, &ctx->sigset);
errno = psr_ctx.psr_error.psr_errno;
@@ -446,9 +448,21 @@ ps_root_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg)
ps_freeprocess(psp);
return ret;
- } else if (!(psm->ps_cmd & PS_START))
- return ps_sendpsmmsg(ctx, psp->psp_fd, psm, msg);
- /* Process has already started .... */
+ } else if (psm->ps_cmd & PS_START) {
+ /* Process has already started .... */
+ return 0;
+ }
+
+ err = ps_sendpsmmsg(ctx, psp->psp_fd, psm, msg);
+ if (err == -1) {
+ logerr("%s: failed to send message to pid %d",
+ __func__, psp->psp_pid);
+ shutdown(psp->psp_fd, SHUT_RDWR);
+ close(psp->psp_fd);
+ psp->psp_fd = -1;
+ ps_dostop(ctx, &psp->psp_pid, &psp->psp_fd);
+ ps_freeprocess(psp);
+ }
return 0;
}