diff -up sudo-1.7.2p2/env.c.orig sudo-1.7.2p2/env.c --- sudo-1.7.2p2/env.c.orig 2010-06-01 13:19:54.000000000 +0200 +++ sudo-1.7.2p2/env.c 2010-06-01 13:26:22.000000000 +0200 @@ -321,7 +321,7 @@ int unsetenv(var) const char *var; { - char **ep; + char **ep = env.envp; size_t len; if (strchr(var, '=') != NULL) { @@ -359,13 +359,15 @@ unsetenv(var) } 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 @@ -433,6 +435,7 @@ sudo_putenv(str, dupcheck, 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) { @@ -451,20 +454,34 @@ sudo_putenv(str, dupcheck, 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; + } } /*