Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/lib/libc/stdlib



> Module Name:  src
> Committed By: christos
> Date:         Thu Sep 23 16:02:41 UTC 2010
> 
> Modified Files:
>       src/lib/libc/stdlib: setenv.c
> 
> Log Message:
> PR/43899: Nicolas Joly: setenv(3)/unsetenv(3) memory leak.
> Partial fix: Don't allocate a new string if the length is equal to the
> old length, because presumably the old string was also nul terminated
> so it has the extra byte needed.
> The real fix is to keep an adjunct array of bits, one for each environmen=
> t
> variable and keep track if the entry was allocated or not so that we can
> free it in unsetenv.
> 
> 
> To generate a diff of this commit:
> cvs rdiff -u -r1.32 -r1.33 src/lib/libc/stdlib/setenv.c

Actual change done in setenv.c rev. 1.33 causes following program
memory leak (while rev. 1.32 does not).

        #include <stdlib.h>

        main()
        {

                while (1)
                        setenv("dummyvar", "dummyval", 1);
        }

And rev. 1.34 introduces lock leak on error path while it leaves
another fixable memory leak.

I guess following patch is worth to be applied.

enami.

Index: lib/libc/stdlib/setenv.c
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/setenv.c,v
retrieving revision 1.34
diff -u -r1.34 setenv.c
--- lib/libc/stdlib/setenv.c    23 Sep 2010 17:30:49 -0000      1.34
+++ lib/libc/stdlib/setenv.c    24 Sep 2010 03:43:19 -0000
@@ -81,7 +81,7 @@
        c = __findenv(name, &offset);
 
        if (__allocenv(offset) == -1)
-               return -1;
+               goto bad;
 
        if (*value == '=')                      /* no `=' in value */
                ++value;
@@ -90,7 +90,7 @@
        if (c != NULL) {
                if (!rewrite)
                        goto good;
-               if (strlen(c) > l_value)        /* old larger; copy over */
+               if (strlen(c) >= l_value)       /* old is enough; copy over */
                        goto copy;
        } else {                                        /* create new slot */
                size = (size_t)(sizeof(char *) * (offset + 2));
@@ -113,6 +113,8 @@
        /* name + `=' + value */
        if ((c = malloc(size + l_value + 2)) == NULL)
                goto bad;
+       if (bit_test(__environ_malloced, offset))
+               free(environ[offset]);
        environ[offset] = c;
        (void)memcpy(c, name, size);
        c += size;



Home | Main Index | Thread Index | Old Index