From: Roy Marples Date: Mon, 22 Jun 2026 19:56:18 +0000 (+0100) Subject: capsicum: Avoid some overflow issues in privsep sysctl X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7891a22dc316e1e3337c459ce8af7073582bdbc4;p=thirdparty%2Fdhcpcd.git capsicum: Avoid some overflow issues in privsep sysctl 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 --- diff --git a/src/privsep-bsd.c b/src/privsep-bsd.c index 4cca33a4..8386a401 100644 --- a/src/privsep-bsd.c +++ b/src/privsep-bsd.c @@ -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;