]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
capsicum: Avoid some overflow issues in privsep sysctl
authorRoy Marples <roy@marples.name>
Mon, 22 Jun 2026 19:56:18 +0000 (20:56 +0100)
committerGitHub <noreply@github.com>
Mon, 22 Jun 2026 19:56:18 +0000 (20:56 +0100)
Limit olen to SIZE_MAX - sizeof(olen).

Ensure our buffer holds is big enough for olen AND newlen
AND is zeroed out as the following sysctl call might return
less data.

Reported by NVIDIA Project Vanessa

src/privsep-bsd.c

index 4cca33a4a379c1905b9a0cda918ab28729f741e9..8386a401270f6151db685508531e20c14d075c86 100644 (file)
@@ -234,9 +234,13 @@ ps_root_dosysctl(unsigned long flags, void *data, size_t len, void **rdata,
                errno = EINVAL;
                return -1;
        }
+       if (oldlen > SIZE_MAX - sizeof(oldlen)) {
+               errno = EINVAL;
+               return -1;
+       }
        memcpy(&newlen, p, sizeof(newlen));
        p += sizeof(newlen);
-       if (p + newlen > e) {
+       if (newlen > (size_t)(e - p)) {
                errno = EINVAL;
                return -1;
        }
@@ -244,7 +248,10 @@ ps_root_dosysctl(unsigned long flags, void *data, size_t len, void **rdata,
 
        if (flags & PS_SYSCTL_OLEN) {
                *rlen = sizeof(oldlen) + oldlen;
-               *rdata = malloc(*rlen);
+               /* The sysctl call below might return less data
+                * and thus we return data we might not want to
+                * so ensure our block zeroed out. */
+               *rdata = calloc(1, *rlen);
                if (*rdata == NULL)
                        return -1;
                oldlenp = (size_t *)*rdata;
@@ -393,7 +400,7 @@ ps_root_sysctl(struct dhcpcd_ctx *ctx, const int *name, unsigned int namelen,
        unsigned long flags = 0;
        size_t olen = (oldp && oldlenp) ? *oldlenp : 0, nolen;
        size_t buflen = sizeof(namelen) + (sizeof(*name) * namelen) +
-           sizeof(oldlenp) + sizeof(newlen) + newlen;
+           sizeof(oldlenp) + sizeof(newlen) + MAX(newlen, olen);
 
        if (ps_bufalloc(ctx, buflen) == -1)
                return -1;