bug-gnulib
[Top][All Lists]
Advanced

[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: Michael Goffioul
Subject: Re: Heap corruption in putenv (Was: JIT crash on simple while-loop [MSVC])
Date: Thu, 14 Feb 2013 13:15:50 -0500

On Thu, Feb 14, 2013 at 1:34 AM, Paul Eggert <address@hidden> wrote:
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
-


Yes, it fixes the problem. No heap corruption reported anymore. Thanks.

Michael.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]