From 7240d8322e8017308907321d7e24e714cedb371f Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Mon, 22 Jun 2026 21:14:11 +0100 Subject: [PATCH] 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 --- src/script.c | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) 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; -- 2.47.3