[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Heap corruption in putenv (Was: JIT crash on simple while-loop [MSVC
From: |
Paul Eggert |
Subject: |
Re: Heap corruption in putenv (Was: JIT crash on simple while-loop [MSVC]) |
Date: |
Wed, 13 Feb 2013 22:34:40 -0800 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2 |
On 02/13/2013 06:54 PM, Michael Goffioul wrote:
> what would be the correct fix?
Does the following fix things? Totally untested; I don't use MSVC.
diff --git a/lib/putenv.c b/lib/putenv.c
index 5f0feda..5108f41 100644
--- a/lib/putenv.c
+++ b/lib/putenv.c
@@ -115,6 +115,38 @@ putenv (char *string)
if (*ep == NULL)
{
+#if HAVE__PUTENV
+ /* Rely on _putenv to allocate the new environment. If other
+ parts of the application use _putenv, the !HAVE__PUTENV code
+ would fight over who owns the environ vector, causing a crash. */
+ if (name_end[1])
+ return _putenv (string);
+ else
+ {
+ /* _putenv ("NAME=") unsets NAME, so invoke _putenv ("NAME=x")
+ to allocate the environ vector and then replace the new
+ entry with "NAME=". */
+ int putenv_result, putenv_errno;
+ char *name_x = malloc (name_end - string + sizeof "=x");
+ if (!name_x)
+ return -1;
+ memcpy (name_x, string, name_end - string + 1);
+ name_x[name_end - string + 1] = 'x';
+ name_x[name_end - string + 2] = 0;
+ putenv_result = _putenv (name_x);
+ putenv_errno = errno;
+ if (putenv_result == 0)
+ for (ep = environ; *ep; ep++)
+ if (*ep == name_x)
+ {
+ *ep = string;
+ break;
+ }
+ free (name_x);
+ __set_errno (putenv_errno);
+ return putenv_result;
+ }
+#else
static char **last_environ = NULL;
char **new_environ = (char **) malloc ((size + 2) * sizeof (char *));
if (new_environ == NULL)
@@ -126,6 +158,7 @@ putenv (char *string)
free (last_environ);
last_environ = new_environ;
environ = new_environ;
+#endif
}
else
*ep = string;
diff --git a/m4/putenv.m4 b/m4/putenv.m4
index 9de5352..03ed4f9 100644
--- a/m4/putenv.m4
+++ b/m4/putenv.m4
@@ -48,3 +48,9 @@ AC_DEFUN([gl_FUNC_PUTENV],
;;
esac
])
+
+# Prerequisites of lib/putenv.c.
+AC_DEFUN([gl_PREREQ_PUTENV],
+[
+ AC_CHECK_FUNCS([_putenv])
+])
diff --git a/modules/putenv b/modules/putenv
index 3321a5e..e39f145 100644
--- a/modules/putenv
+++ b/modules/putenv
@@ -14,6 +14,7 @@ configure.ac:
gl_FUNC_PUTENV
if test $REPLACE_PUTENV = 1; then
AC_LIBOBJ([putenv])
+ gl_PREREQ_PUTENV
fi
gl_STDLIB_MODULE_INDICATOR([putenv])
@@ -27,4 +28,3 @@ LGPL
Maintainer:
Jim Meyering, glibc
-