FS#18608 - [zlib] Memory leak

Attached to Project: Arch Linux
Opened by Alexandre Bique (babali) - Monday, 08 March 2010, 16:23 GMT
Last edited by Pierre Schmitz (Pierre) - Monday, 15 March 2010, 11:08 GMT
Task Type Bug Report
Category Upstream Bugs
Status Closed
Assigned To Pierre Schmitz (Pierre)
Architecture All
Severity Critical
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 3
Private No

Details

Description:

Hi there is a memory leak in zlib : we lost 5 bytes each time we open a stream with zlib which is very critical for a server!

Additional info:
* package version(s) 1.2.3.9-1
* config and/or log files etc.


Steps to reproduce:

#include <zlib.h>
#include <stdlib.h>

void just_do_it(void)
{
char buffer[] = "<html></html>";
gzFile file = gzopen("tutu", "wb1");
gzprintf(file, "<!-- %s -->\n", "http://www.twenga.com");
gzwrite(file, buffer, sizeof (buffer));
gzclose(file);
}

int main(int argc, char ** argv)
{
for (int i = 0; i < 1000; ++i)
just_do_it();
return 0;
}


gcc toto.c -lz -std=c99

valgrind_mleak ./a.out
==28127== Memcheck, a memory error detector
==28127== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==28127== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==28127== Command: ./a.out
==28127==
==28127==
==28127== HEAP SUMMARY:
==28127== in use at exit: 5,000 bytes in 1,000 blocks
==28127== total heap usage: 9,000 allocs, 8,000 frees, 284,701,000 bytes allocated
==28127==
==28127== 5,000 bytes in 1,000 blocks are definitely lost in loss record 1 of 1
==28127== at 0x4C23E03: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28127== by 0x400E89: gz_open (in /home/abique/a.out)
==28127== by 0x400A05: just_do_it (toto.c:7)
==28127== by 0x400A67: main (toto.c:16)
==28127==
==28127== LEAK SUMMARY:
==28127== definitely lost: 5,000 bytes in 1,000 blocks
==28127== indirectly lost: 0 bytes in 0 blocks
==28127== possibly lost: 0 bytes in 0 blocks
==28127== still reachable: 0 bytes in 0 blocks
==28127== suppressed: 0 bytes in 0 blocks
==28127==
==28127== For counts of detected and suppressed errors, rerun with: -v
==28127== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 7 from 7)
This task depends upon

Closed by  Pierre Schmitz (Pierre)
Monday, 15 March 2010, 11:08 GMT
Reason for closing:  Fixed
Additional comments about closing:  fixed in zlib version 1.2.4
Comment by Linas (Linas) - Monday, 08 March 2010, 18:35 GMT
Verified. The leak comes from:
state->path = malloc(strlen(path) + 1);
which is never freed.
You can change "tutu" to a larger string to make bigger leak.

Attached patch fixes it.
Comment by Pierre Schmitz (Pierre) - Monday, 08 March 2010, 19:37 GMT
Thanks for discovering this issue. I have reported this to the zlib mailing list. The patch looks fine to me. (but I'll need to test)
Comment by Linas (Linas) - Monday, 08 March 2010, 20:25 GMT
Sure.


Since zlib-devel is private, you may also want to report another valgrind error when doing just gzopen + gzclose:
Conditional jump or move depends on uninitialised value(s)
at 0x408A7A: deflate (deflate.c:596)
by 0x402744: gz_comp (gzwrite.c:93)
by 0x4029D5: gzclose_w (gzwrite.c:522)

strm->next_in isn't initialised by gz_open, but gzclose calls deflate, which checks if (strm->next_in == Z_NULL && strm->avail_in != 0)
This seems harmless since strm->avail_in *is* initialised to 0, and it won't enter the condition anyway, but the conditions should be reversed to avoid that warning.
Comment by Alexandre Bique (babali) - Tuesday, 09 March 2010, 10:54 GMT
thank you for the bugfix ! :)
Comment by Pierre Schmitz (Pierre) - Wednesday, 10 March 2010, 18:33 GMT
There should be a new upstream release of zlib within the next days. I would suggest to wait for that. I could upload a patched version on demand for those who have problems compiling it though.

@Linas: Maybe this FaQ entry is interesting for you: http://zlib.net/zlib_faq.html#faq36

Loading...