On Thu, Feb 14, 2013 at 1:34 AM, Paul Eggert <egg...@cs.ucla.edu> 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