From: Roy Marples Date: Mon, 22 Jun 2026 20:14:11 +0000 (+0100) Subject: script: Fix buffer over and under flows in script_buftoenv X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;p=thirdparty%2Fdhcpcd.git script: Fix buffer over and under flows in script_buftoenv Enforce we have a buffer and it is terminated. Rework code so that we no longer assert. Reported by NVIDIA Project Vanessa --- diff --git a/src/script.c b/src/script.c index 1edf0c22..ca273e2b 100644 --- a/src/script.c +++ b/src/script.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -165,20 +164,30 @@ script_buftoenv(struct dhcpcd_ctx *ctx, char *buf, size_t len) char **env, **envp, *bufp, *endp; size_t nenv; - /* Count the terminated env strings. - * Assert that the terminations are correct. */ + /* We should have something to process */ + if (buf == NULL || len == 0) { + errno = EINVAL; + return NULL; + } + + /* Ensure the buffer ends with NUL */ + if (buf[len - 1] != '\0') { + errno = EINVAL; + return NULL; + } + + /* Count the NUL-terminated env strings */ nenv = 0; endp = buf + len; for (bufp = buf; bufp < endp; bufp++) { if (*bufp == '\0') { -#ifndef NDEBUG - if (bufp + 1 < endp) - assert(*(bufp + 1) != '\0'); -#endif + /* Skip consecutive NULs safely without crashing */ + while (bufp + 1 < endp && *(bufp + 1) == '\0') { + bufp++; + } nenv++; } } - assert(*(bufp - 1) == '\0'); if (nenv == 0) return NULL; @@ -192,11 +201,23 @@ script_buftoenv(struct dhcpcd_ctx *ctx, char *buf, size_t len) bufp = buf; envp = ctx->script_env; - *envp++ = bufp++; - endp--; /* Avoid setting the last \0 to an invalid pointer */ - for (; bufp < endp; bufp++) { - if (*bufp == '\0') - *envp++ = bufp + 1; + + /* If first char is NUL, skip leading empty strings if any, + * or handle them gracefully */ + while (bufp < endp && *bufp == '\0') + bufp++; + if (bufp < endp) + *envp++ = bufp; + + /* Walk and capture pointers to each environment variable */ + for (; bufp < endp - 1; bufp++) { + if (*bufp == '\0') { + /* Skip consecutive NULs */ + while (bufp < endp - 1 && *(bufp + 1) == '\0') + bufp++; + if (bufp + 1 < endp) + *envp++ = bufp + 1; + } } *envp = NULL;