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

Libc6 2.0.5c has a leak in inet_ntoa



I should have sent this email much earlier since I've found this 
problem more than a week ago:
Libc6 2.0.5c has a leak in inet_ntoa.
This simple program will prove it:

        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>

        void main(void) {
            char *a;
            struct in_addr s;
            while(1) {
                a=inet_ntoa(s);
            }
        }

Run it and watch it grow.
This explains the diald 0.16.4-10 memory leak (and might explain the 
nfsd leak too).

The inside story is: due to a problem with libc6, libc_create_key is 
not declared as a weak symbol of libpthread, and it's not wrapped in 
a macro which detects if the program is linked with libpthread.
The result is that during the first call to inet_ntoa(), a libc_once 
initialization routine is called, it thinks it's linked with 
libpthread and attempts to create a thread-specific return buffer 
through libc_create_key. It  believes that the call completed 
successfully. It does not setup a process-wide buffer.
For each invocation of inet_ntoa, libc_get_key returns null, and 
inet_ntoa thinks it's the first time it's been called and mallocs() a 
buffer. It normally stores it with libc_set_key, but it fails (and 
this is not reported).
Every time the function is called, 16 bytes are lost.

The normal operation would be:
1) Libpthread is not present.
   The libc_once initialization routine detects that libc_create_key 
   isn't there and sets up a global buffer. Inet_ntoa uses this 
buffer.
2) Libpthread is present.
   The libc_once initialization routine creates thread-specific keys.
   During the first invocation of inet_ntoa in each thread,
   the thread-specific key is accessed. If null, a buffer is allocated
   with malloc, once per thread, and is stored for future use.

This is what libc6 2.0.6 does (I've checked).

In the meantime, you can link programs which do heavy inet_ntoa with 
libpthread, it will cure the leak (diald 0.16.4-11 does this, as a 
temporary measure while waiting for libc6 2.0.6).

I hope this is not too confusing :-)

Phil.



--
TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-devel-request@lists.debian.org . 
Trouble?  e-mail to templin@bucknell.edu .


Reply to: