diff options
| author | Roy Marples <roy@marples.name> | 2020-06-02 15:50:17 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-06-02 15:50:17 +0100 |
| commit | 828e858d3d7bbdb82bec7cd56616795426861783 (patch) | |
| tree | 8a0b14e8f7c4ffca25bbd8654b68d93c99899dda /src/privsep-root.c | |
| parent | 0a8158b5a0d6e8287c2127f96c95b7799abb3e23 (diff) | |
| download | dhcpcd-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.c | 20 |
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; } |
