From c31ed2cd22edab8afd95f2f33f42db30a618c40e Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 28 May 2010 09:42:50 -0400 Subject: [PATCH] Handle duplicate variables in the environment. For unsetenv(), keep looking even after remove the first instance. For sudo_putenv(), check for and remove dupes after we replace an existing value. --- plugins/sudoers/env.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/plugins/sudoers/env.c b/plugins/sudoers/env.c index 6041f5713..ce1e7e612 100644 --- a/plugins/sudoers/env.c +++ b/plugins/sudoers/env.c @@ -336,7 +336,7 @@ int #endif unsetenv(const char *var) { - char **ep; + char **ep = env.envp; size_t len; if (strchr(var, '=') != NULL) { @@ -354,13 +354,15 @@ unsetenv(const char *var) #endif len = strlen(var); - for (ep = env.envp; *ep; ep++) { + while (*ep != NULL) { if (strncmp(var, *ep, len) == 0 && (*ep)[len] == '=') { /* Found it; shift remainder + NULL over by one and update len. */ memmove(ep, ep + 1, (env.env_len - (ep - env.envp)) * sizeof(char *)); env.env_len--; - break; + /* Keep going, could be multiple instances of the var. */ + } else { + ep++; } } #ifndef UNSETENV_VOID @@ -401,6 +403,7 @@ sudo_putenv(char *str, int dupcheck, int overwrite) { char **ep; size_t len; + int found = FALSE; /* Make sure there is room for the new entry plus a NULL. */ if (env.env_len + 2 > env.env_size) { @@ -418,20 +421,34 @@ sudo_putenv(char *str, int dupcheck, int overwrite) #endif if (dupcheck) { - len = (strchr(str, '=') - str) + 1; - for (ep = env.envp; *ep; ep++) { + len = (strchr(str, '=') - str) + 1; + for (ep = env.envp; !found && *ep != NULL; ep++) { + if (strncmp(str, *ep, len) == 0) { + if (overwrite) + *ep = str; + found = TRUE; + } + } + /* Prune out duplicate variables. */ + if (found && overwrite) { + while (*ep != NULL) { if (strncmp(str, *ep, len) == 0) { - if (overwrite) - *ep = str; - return; + memmove(ep, ep + 1, + (env.env_len - (ep - env.envp)) * sizeof(char *)); + env.env_len--; + } else { + ep++; } } - } else - ep = env.envp + env.env_len; + } + } - env.env_len++; - *ep++ = str; - *ep = NULL; + if (!found) { + ep = env.envp + env.env_len; + env.env_len++; + *ep++ = str; + *ep = NULL; + } } /* -- 2.40.0