Module Name:    src
Committed By:   christos
Date:           Wed Nov  3 15:01:07 UTC 2010

Modified Files:
        src/lib/libc/stdlib: getenv.c local.h putenv.c setenv.c

Log Message:
Handle the case where a program attempted to cleanup the environment by
setting *environ = NULL;


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/lib/libc/stdlib/getenv.c
cvs rdiff -u -r1.4 -r1.5 src/lib/libc/stdlib/local.h
cvs rdiff -u -r1.17 -r1.18 src/lib/libc/stdlib/putenv.c
cvs rdiff -u -r1.41 -r1.42 src/lib/libc/stdlib/setenv.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/stdlib/getenv.c
diff -u src/lib/libc/stdlib/getenv.c:1.28 src/lib/libc/stdlib/getenv.c:1.29
--- src/lib/libc/stdlib/getenv.c:1.28	Mon Nov  1 23:44:05 2010
+++ src/lib/libc/stdlib/getenv.c	Wed Nov  3 11:01:07 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: getenv.c,v 1.28 2010/11/02 03:44:05 enami Exp $	*/
+/*	$NetBSD: getenv.c,v 1.29 2010/11/03 15:01:07 christos Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)getenv.c	8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: getenv.c,v 1.28 2010/11/02 03:44:05 enami Exp $");
+__RCSID("$NetBSD: getenv.c,v 1.29 2010/11/03 15:01:07 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -154,6 +154,28 @@
 }
 
 /*
+ * Handle the case where a program tried to cleanup the environment
+ * by setting *environ = NULL; we attempt to cleanup all the malloced
+ * environ entries and we make sure that the entry following the new
+ * entry is NULL.
+ */
+void
+__scrubenv(int offset)
+{
+	if (environ[++offset] == NULL)
+		return;
+
+	while (environ[offset] &&
+	    environ[offset] == __environ_malloced[offset]) {
+		free(__environ_malloced[offset]);
+		environ[offset] = __environ_malloced[offset] = NULL;
+		offset++;
+	}
+
+	environ[offset] = __environ_malloced[offset] = NULL;
+}
+
+/*
  * __findenv --
  *	Returns pointer to value associated with name, if any, else NULL.
  *	Sets offset to be the offset of the name/value combination in the

Index: src/lib/libc/stdlib/local.h
diff -u src/lib/libc/stdlib/local.h:1.4 src/lib/libc/stdlib/local.h:1.5
--- src/lib/libc/stdlib/local.h:1.4	Sat Sep 25 14:11:40 2010
+++ src/lib/libc/stdlib/local.h	Wed Nov  3 11:01:07 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: local.h,v 1.4 2010/09/25 18:11:40 tron Exp $	*/
+/*	$NetBSD: local.h,v 1.5 2010/11/03 15:01:07 christos Exp $	*/
 
 /*
  * Copyright (c) 1997 Christos Zoulas.  All rights reserved.
@@ -26,6 +26,7 @@
 
 char *__findenv(const char *, int *);
 int __allocenv(int);
+void __scrubenv(int);
 
 #ifdef _REENTRANT
 extern rwlock_t __environ_lock;

Index: src/lib/libc/stdlib/putenv.c
diff -u src/lib/libc/stdlib/putenv.c:1.17 src/lib/libc/stdlib/putenv.c:1.18
--- src/lib/libc/stdlib/putenv.c:1.17	Mon Oct 25 16:35:36 2010
+++ src/lib/libc/stdlib/putenv.c	Wed Nov  3 11:01:07 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: putenv.c,v 1.17 2010/10/25 20:35:36 njoly Exp $	*/
+/*	$NetBSD: putenv.c,v 1.18 2010/11/03 15:01:07 christos Exp $	*/
 
 /*-
  * Copyright (c) 1988, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)putenv.c	8.2 (Berkeley) 3/27/94";
 #else
-__RCSID("$NetBSD: putenv.c,v 1.17 2010/10/25 20:35:36 njoly Exp $");
+__RCSID("$NetBSD: putenv.c,v 1.18 2010/11/03 15:01:07 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -78,6 +78,8 @@
 	}
 
 	environ[offset] = str;
+	if (p == NULL)
+		__scrubenv(offset);
 	rwlock_unlock(&__environ_lock);
 	return 0;
 bad:

Index: src/lib/libc/stdlib/setenv.c
diff -u src/lib/libc/stdlib/setenv.c:1.41 src/lib/libc/stdlib/setenv.c:1.42
--- src/lib/libc/stdlib/setenv.c:1.41	Sat Oct 16 07:23:41 2010
+++ src/lib/libc/stdlib/setenv.c	Wed Nov  3 11:01:07 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: setenv.c,v 1.41 2010/10/16 11:23:41 njoly Exp $	*/
+/*	$NetBSD: setenv.c,v 1.42 2010/11/03 15:01:07 christos Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)setenv.c	8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: setenv.c,v 1.41 2010/10/16 11:23:41 njoly Exp $");
+__RCSID("$NetBSD: setenv.c,v 1.42 2010/11/03 15:01:07 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -59,7 +59,7 @@
 int
 setenv(const char *name, const char *value, int rewrite)
 {
-	char *c;
+	char *c, *f;
 	size_t l_value, size;
 	int offset;
 
@@ -81,14 +81,14 @@
 		return -1;
 
 	/* find if already exists */
-	c = __findenv(name, &offset);
+	f = __findenv(name, &offset);
 
 	if (__allocenv(offset) == -1)
 		goto bad;
 
 	l_value = strlen(value);
 
-	if (c != NULL) {
+	if (f != NULL) {
 		if (!rewrite)
 			goto good;
 		/*
@@ -97,7 +97,8 @@
 		 * existing value.
 		 */
 		if (environ[offset] == __environ_malloced[offset] &&
-		    strlen(c) >= l_value) {
+		    strlen(f) >= l_value) {
+			c = f;
 			goto copy;
 		}
 	}
@@ -110,6 +111,10 @@
 
 	environ[offset] = c;
 	__environ_malloced[offset] = c;
+
+	if (f == NULL)
+		__scrubenv(offset);
+
 	(void)memcpy(c, name, size);
 	c += size;
 	*c++ = '=';

Reply via email to