--- /usr/src/lib/libc/stdlib/setenv.c	Fri Mar 22 15:53:10 2002
+++ setenv.c	Wed Jul  5 20:47:35 2006
@@ -40,9 +40,12 @@
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
 
 char *__findenv(const char *, int *);
 
+static uint8_t dynamicEnv = 0;			/* Env vars were copied */
+
 /*
  * setenv --
  *	Set the value of the environmental variable "name" to be
@@ -59,6 +62,18 @@
 	char *c;
 	int l_value, offset;
 
+	/*
+	 * Make copies of environment variables to allow for
+	 * reallocation.  This stops a potential memory leak
+	 * when resetting a variable with larger values.
+	 */
+	if (!dynamicEnv) {
+		for (offset = 0; environ[offset]; offset++)
+			if ((environ[offset] = strdup(environ[offset])) == NULL)
+				return (-1);
+		dynamicEnv = 1;
+	}
+
 	if (*value == '=')			/* no `=' in value */
 		++value;
 	l_value = strlen(value);
@@ -74,27 +89,21 @@
 		char **p;
 
 		for (p = environ, cnt = 0; *p; ++p, ++cnt);
-		if (alloced == environ) {			/* just increase size */
-			p = (char **)realloc((char *)environ,
-			    (size_t)(sizeof(char *) * (cnt + 2)));
-			if (!p)
-				return (-1);
-			alloced = environ = p;
-		}
-		else {				/* get new space */
-						/* copy old entries into it */
-			p = malloc((size_t)(sizeof(char *) * (cnt + 2)));
-			if (!p)
-				return (-1);
+		p = (char **)realloc((char *)alloced,
+		    (size_t)(sizeof(char *) * (cnt + 2)));
+		if (!p)
+			return (-1);
+		if (alloced != environ) {		/* alloced environ */
+			/* copy old entries into it */
 			bcopy(environ, p, cnt * sizeof(char *));
-			alloced = environ = p;
 		}
+		alloced = environ = p;
 		environ[cnt + 1] = NULL;
 		offset = cnt;
 	}
 	for (c = (char *)name; *c && *c != '='; ++c);	/* no `=' in name */
 	if (!(environ[offset] =			/* name + `=' + value */
-	    malloc((size_t)((int)(c - name) + l_value + 2))))
+	    reallocf(environ[offset], (size_t)((int)(c - name) + l_value + 2))))
 		return (-1);
 	for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
 	for (*c++ = '='; (*c++ = *value++); );
@@ -113,8 +122,11 @@
 	char **p;
 	int offset;
 
-	while (__findenv(name, &offset))	/* if set multiple times */
+	while (__findenv(name, &offset)) {	/* if set multiple times */
+		if (dynamicEnv)
+			free(environ[offset]);
 		for (p = &environ[offset];; ++p)
 			if (!(*p = *(p + 1)))
 				break;
+	}
 }

