diff options
author | Eric Biggers <ebiggers3@gmail.com> | 2015-01-07 12:10:52 +0530 |
---|---|---|
committer | Siddhesh Poyarekar <siddhesh@redhat.com> | 2015-01-07 12:10:52 +0530 |
commit | d5b1c5ed8bd9515505d4177f105c19ea375106ae (patch) | |
tree | 5e7164983b8a3e4f3a16e8069495a46c8c33d7b3 /stdlib/setenv.c | |
parent | fb87ee96d7dd0714d52004e4676629f8d9db732f (diff) | |
download | glibc-d5b1c5ed8bd9515505d4177f105c19ea375106ae.tar.gz glibc-d5b1c5ed8bd9515505d4177f105c19ea375106ae.tar.xz glibc-d5b1c5ed8bd9515505d4177f105c19ea375106ae.zip |
setenv fix memory leak when setting large, duplicate string (BZ #17658)
glibc maintains a binary tree of environment strings it malloc()ed itself. However, it's possible for it to malloc() a string, then find that an identical string is already in the tree. In this case, the memory is leaked and is not freed if the application later calls __libc_freeres(). Fix this by freeing 'new_value' when it's unneeded. Test case: #include <stdlib.h> #include <string.h> int main() { char *p = calloc(100000, 1); memset(p, 'A', 99999); setenv("TESTVAR", p, 1); setenv("TESTVAR", p, 1); free(p); } Leak that was reported by valgrind: 100,008 bytes in 1 blocks are definitely lost in loss record 1 of 1 at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x4E6B3D4: __add_to_environ (setenv.c:176) by 0x4C31B8F: setenv (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x400642: main (in /mnt/tmpfs/a.out)
Diffstat (limited to 'stdlib/setenv.c')
-rw-r--r-- | stdlib/setenv.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/stdlib/setenv.c b/stdlib/setenv.c index 710da1383c..b60c4f0151 100644 --- a/stdlib/setenv.c +++ b/stdlib/setenv.c @@ -217,6 +217,13 @@ __add_to_environ (name, value, combined, replace) /* And remember the value. */ STORE_VALUE (np); } +#ifdef USE_TSEARCH + else + { + if (__glibc_unlikely (! use_alloca)) + free (new_value); + } +#endif } *ep = np; |