]> granicus.if.org Git - sudo/commitdiff
Handle duplicate variables in the environment. For unsetenv(),
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 28 May 2010 13:42:50 +0000 (09:42 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 28 May 2010 13:42:50 +0000 (09:42 -0400)
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

index 6041f5713e0dcb15de2e6636ed0d08684123b4b0..ce1e7e612731366b1b7f574383f1f8a4bf6ddd0a 100644 (file)
@@ -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;
+    }
 }
 
 /*