]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
privsep: ps_root_readfile should return the real file size master
authorRoy Marples <roy@marples.name>
Sat, 20 Jun 2026 08:49:44 +0000 (09:49 +0100)
committerGitHub <noreply@github.com>
Sat, 20 Jun 2026 08:49:44 +0000 (09:49 +0100)
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.

src/common.c
src/privsep-root.c

index 953db6f6a04e3f7a40659847279593ea812cf572..1cb2f26b8d18811a0400a315a8acd65c2e9dcf11 100644 (file)
@@ -124,6 +124,10 @@ readfile(const char *file, void **data, size_t *len)
                return -1;
        if (fstat(fd, &st) == -1)
                goto out;
                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);
        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;
        }
                *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';
 out:
        close(fd);
        if (bytes == -1)
                return -1;
        buf = *data;
        buf[bytes] = '\0';
-       return bytes + 1;
+       return bytes;
 }
 
 ssize_t
 }
 
 ssize_t
index 70bad9c31a1799278e5c508400737f900ef5ef8f..798076f23e75667fa93718ff42748093e73756a6 100644 (file)
@@ -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;
                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:
                }
                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)
 {
 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;
 
        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
 }
 
 ssize_t