Module Name: src Committed By: tron Date: Sat Oct 2 16:56:03 UTC 2010
Modified Files: src/lib/libc/stdlib: putenv.c setenv.c Log Message: Restore binary compatibility with application which use putenv(3) on contant strings (e.g. postdrop(1)): - Don't write to the environment string passed to putenv(3). - Don't overwrite the value of an existing in setenv(3) unless the memory was actually allocated by setenv(3). To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 src/lib/libc/stdlib/putenv.c cvs rdiff -u -r1.39 -r1.40 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/putenv.c diff -u src/lib/libc/stdlib/putenv.c:1.14 src/lib/libc/stdlib/putenv.c:1.15 --- src/lib/libc/stdlib/putenv.c:1.14 Sat Oct 2 10:05:55 2010 +++ src/lib/libc/stdlib/putenv.c Sat Oct 2 16:56:03 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: putenv.c,v 1.14 2010/10/02 10:05:55 tron Exp $ */ +/* $NetBSD: putenv.c,v 1.15 2010/10/02 16:56:03 tron 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.14 2010/10/02 10:05:55 tron Exp $"); +__RCSID("$NetBSD: putenv.c,v 1.15 2010/10/02 16:56:03 tron Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -54,7 +54,8 @@ int putenv(char *str) { - char *p, *equal; + char *name, *equal, *p; + size_t namelen; int offset; _DIAGASSERT(str != NULL); @@ -62,12 +63,19 @@ if ((equal = strchr(str, '=')) == NULL) return -1; - if (rwlock_wrlock(&__environ_lock) != 0) + namelen = equal - str; + if ((name = malloc(namelen + 1)) == NULL) return -1; + (void)memcpy(name, str, namelen); + name[namelen] = '\0'; - *equal = '\0'; - p = __findenv(str, &offset); - *equal = '='; + if (rwlock_wrlock(&__environ_lock) != 0) { + free(name); + return -1; + } + + p = __findenv(name, &offset); + free(name); if (__allocenv(offset) == -1) goto bad; Index: src/lib/libc/stdlib/setenv.c diff -u src/lib/libc/stdlib/setenv.c:1.39 src/lib/libc/stdlib/setenv.c:1.40 --- src/lib/libc/stdlib/setenv.c:1.39 Fri Oct 1 20:11:32 2010 +++ src/lib/libc/stdlib/setenv.c Sat Oct 2 16:56:03 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: setenv.c,v 1.39 2010/10/01 20:11:32 christos Exp $ */ +/* $NetBSD: setenv.c,v 1.40 2010/10/02 16:56:03 tron 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.39 2010/10/01 20:11:32 christos Exp $"); +__RCSID("$NetBSD: setenv.c,v 1.40 2010/10/02 16:56:03 tron Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -83,8 +83,15 @@ if (c != NULL) { if (!rewrite) goto good; - if (strlen(c) >= l_value) /* old is enough; copy over */ + /* + * Check whether the buffer was allocated via setenv(3) and + * whether there is enough space. If so simply overwrite the + * existing value. + */ + if (environ[offset] == __environ_malloced[offset] && + strlen(c) >= l_value) { goto copy; + } } for (cc = name; *cc && *cc != '='; ++cc) /* no `=' in name */ continue;