From: Roy Marples Date: Sat, 20 Jun 2026 08:49:44 +0000 (+0100) Subject: privsep: ps_root_readfile should return the real file size X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=HEAD;p=thirdparty%2Fdhcpcd.git privsep: ps_root_readfile should return the real file size readfile NUL terminates the buffer to make things easy. We need to transmit this over IPC just ensure the receiver has a big enough buffer, again to make things easy. So on success, we need to trim the NUL from the returned length so the actual file size is accurate. --- diff --git a/src/common.c b/src/common.c index 953db6f6..1cb2f26b 100644 --- a/src/common.c +++ b/src/common.c @@ -124,6 +124,10 @@ readfile(const char *file, void **data, size_t *len) return -1; if (fstat(fd, &st) == -1) goto out; + + /* Ensure that what we read is NUL terminated + * because it's mainly text files and this just + * makes it easier. */ nlen = (size_t)st.st_size + 1; if (nlen > *len) { void *ndata = realloc(*data, nlen); @@ -132,14 +136,15 @@ readfile(const char *file, void **data, size_t *len) *data = ndata; *len = nlen; } - bytes = read(fd, *data, *len); + bytes = read(fd, *data, *len - 1); + out: close(fd); if (bytes == -1) return -1; buf = *data; buf[bytes] = '\0'; - return bytes + 1; + return bytes; } ssize_t diff --git a/src/privsep-root.c b/src/privsep-root.c index 70bad9c3..798076f2 100644 --- a/src/privsep-root.c +++ b/src/privsep-root.c @@ -529,7 +529,10 @@ ps_root_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg) err = readfile(data, &ctx->ps_buf, &ctx->ps_buflen); if (err != -1) { rdata = ctx->ps_buf; - rlen = (size_t)err; + /* We know the buffer is NUL terminated. + * Send it over IPC to ensure the receiver has + * enough space for it as well. */ + rlen = (size_t)err + 1; } break; case PS_WRITEFILE: @@ -1040,11 +1043,18 @@ ssize_t ps_root_readfile(struct dhcpcd_ctx *ctx, const char *file, void **data, size_t *len) { + ssize_t err; + if (ps_sendcmd(ctx, PS_ROOT_FD(ctx), PS_READFILE, 0, file, strlen(file) + 1) == -1) return -1; - return ps_root_mreaderror(ctx, data, len); + err = ps_root_mreaderror(ctx, data, len); + if (err == -1) + return -1; + + /* The returned length should not include the NUL terminator */ + return err - 1; } ssize_t