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++ = '=';