From: Roy Marples Date: Sun, 10 May 2020 10:05:23 +0000 (+0100) Subject: privsep: Copy back ioctl data X-Git-Tag: v9.1.0~83 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=606f8a3f1b826d36404aa5d79144ad1091a58976;p=thirdparty%2Fdhcpcd.git privsep: Copy back ioctl data --- diff --git a/src/privsep-bsd.c b/src/privsep-bsd.c index 1cd91c8f..b64040d6 100644 --- a/src/privsep-bsd.c +++ b/src/privsep-bsd.c @@ -94,7 +94,7 @@ ps_root_ioctldom(struct dhcpcd_ctx *ctx, uint8_t domain, unsigned long request, if (ps_sendcmd(ctx, ctx->ps_root_fd, domain, request, data, len) == -1) return -1; - return ps_root_readerror(ctx); + return ps_root_readerror(ctx, data, len); } ssize_t @@ -119,5 +119,5 @@ ps_root_route(struct dhcpcd_ctx *ctx, void *data, size_t len) if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_ROUTE, 0, data, len) == -1) return -1; - return ps_root_readerror(ctx); + return ps_root_readerror(ctx, data, len); } diff --git a/src/privsep-linux.c b/src/privsep-linux.c index 4321f361..98403f5c 100644 --- a/src/privsep-linux.c +++ b/src/privsep-linux.c @@ -121,7 +121,7 @@ ps_root_sendnetlink(struct dhcpcd_ctx *ctx, int protocol, struct msghdr *msg) if (ps_sendmsg(ctx, ctx->ps_root_fd, PS_ROUTE, (unsigned long)protocol, msg) == -1) return -1; - return ps_root_readerror(ctx); + return ps_root_readerror(ctx, NULL, 0); } ssize_t @@ -146,5 +146,5 @@ ps_root_writepathuint(struct dhcpcd_ctx *ctx, const char *path, if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_WRITEPATHUINT, 0, buf, len) == -1) return -1; - return ps_root_readerror(ctx); + return ps_root_readerror(ctx, NULL, 0); } diff --git a/src/privsep-root.c b/src/privsep-root.c index c3b95e24..dcfe3091 100644 --- a/src/privsep-root.c +++ b/src/privsep-root.c @@ -62,6 +62,8 @@ struct psr_error struct psr_ctx { struct dhcpcd_ctx *psr_ctx; struct psr_error psr_error; + size_t psr_datalen; + void *psr_data; }; static void @@ -78,10 +80,15 @@ ps_root_readerrorcb(void *arg) struct psr_ctx *psr_ctx = arg; struct dhcpcd_ctx *ctx = psr_ctx->psr_ctx; struct psr_error *psr_error = &psr_ctx->psr_error; + struct iovec iov[] = { + { .iov_base = psr_error, .iov_len = sizeof(*psr_error) }, + { .iov_base = psr_ctx->psr_data, + .iov_len = psr_ctx->psr_datalen }, + }; ssize_t len; int exit_code = EXIT_FAILURE; - len = read(ctx->ps_root_fd, psr_error, sizeof(*psr_error)); + len = readv(ctx->ps_root_fd, iov, __arraycount(iov)); if (len == 0 || len == -1) { logerr(__func__); psr_error->psr_result = -1; @@ -97,9 +104,12 @@ ps_root_readerrorcb(void *arg) } ssize_t -ps_root_readerror(struct dhcpcd_ctx *ctx) +ps_root_readerror(struct dhcpcd_ctx *ctx, void *data, size_t len) { - struct psr_ctx psr_ctx = { .psr_ctx = ctx }; + struct psr_ctx psr_ctx = { + .psr_ctx = ctx, + .psr_data = data, .psr_datalen = len, + }; if (eloop_event_add(ctx->ps_eloop, ctx->ps_root_fd, ps_root_readerrorcb, &psr_ctx) == -1) @@ -115,18 +125,23 @@ ps_root_readerror(struct dhcpcd_ctx *ctx) } static ssize_t -ps_root_writeerror(struct dhcpcd_ctx *ctx, ssize_t result) +ps_root_writeerror(struct dhcpcd_ctx *ctx, ssize_t result, + void *data, size_t len) { struct psr_error psr = { .psr_result = result, .psr_errno = errno, }; + struct iovec iov[] = { + { .iov_base = &psr, .iov_len = sizeof(psr) }, + { .iov_base = data, .iov_len = len }, + }; #ifdef PRIVSEP_DEBUG logdebugx("%s: result %zd errno %d", __func__, result, errno); #endif - return write(ctx->ps_root_fd, &psr, sizeof(psr)); + return writev(ctx->ps_root_fd, iov, __arraycount(iov)); } static ssize_t @@ -386,7 +401,7 @@ ps_root_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg) break; } - return ps_root_writeerror(ctx, err); + return ps_root_writeerror(ctx, err, data, len); } /* Receive from state engine, do an action. */ @@ -539,7 +554,7 @@ ps_root_script(const struct interface *ifp, const void *data, size_t len) buf, slen + len) == -1) return -1; - return ps_root_readerror(ifp->ctx); + return ps_root_readerror(ifp->ctx, NULL, 0); } ssize_t @@ -556,7 +571,7 @@ ps_root_ioctl(struct dhcpcd_ctx *ctx, ioctl_request_t req, void *data, if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_IOCTL, req, data, len) == -1) return -1; #endif - return ps_root_readerror(ctx); + return ps_root_readerror(ctx, data, len); } static ssize_t @@ -577,7 +592,7 @@ ps_root_fileop(struct dhcpcd_ctx *ctx, const char *path, uint8_t op) if (ps_sendcmd(ctx, ctx->ps_root_fd, op, 0, buf, len) == -1) return -1; - return ps_root_readerror(ctx); + return ps_root_readerror(ctx, NULL, 0); } diff --git a/src/privsep-root.h b/src/privsep-root.h index 43727593..46608792 100644 --- a/src/privsep-root.h +++ b/src/privsep-root.h @@ -34,7 +34,7 @@ pid_t ps_root_start(struct dhcpcd_ctx *ctx); int ps_root_stop(struct dhcpcd_ctx *ctx); -ssize_t ps_root_readerror(struct dhcpcd_ctx *); +ssize_t ps_root_readerror(struct dhcpcd_ctx *, void *, size_t); ssize_t ps_root_docopychroot(struct dhcpcd_ctx *, const char *); ssize_t ps_root_copychroot(struct dhcpcd_ctx *, const char *); ssize_t ps_root_ioctl(struct dhcpcd_ctx *, ioctl_request_t, void *, size_t); diff --git a/src/privsep-sun.c b/src/privsep-sun.c index aa5e0e93..ed6e5d3a 100644 --- a/src/privsep-sun.c +++ b/src/privsep-sun.c @@ -98,7 +98,7 @@ ps_root_ioctl6(struct dhcpcd_ctx *ctx, unsigned long request, void *data, size_t if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_IOCTL6, request, data, len) == -1) return -1; - return ps_root_readerror(ctx); + return ps_root_readerror(ctx, data, len); } ssize_t @@ -107,5 +107,5 @@ ps_root_route(struct dhcpcd_ctx *ctx, void *data, size_t len) if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_ROUTE, 0, data, len) == -1) return -1; - return ps_root_readerror(ctx); + return ps_root_readerror(ctx, data, len); } diff --git a/src/privsep.c b/src/privsep.c index bfc8860d..51fdf7b7 100644 --- a/src/privsep.c +++ b/src/privsep.c @@ -490,7 +490,6 @@ ps_unrollmsg(struct msghdr *msg, struct ps_msghdr *psm, return 0; } - ssize_t ps_sendpsmmsg(struct dhcpcd_ctx *ctx, int fd, struct ps_msghdr *psm, const struct msghdr *msg)