linux glibc sometimes improperly free()'s objects created by __libc_memalign()
Bradley C. Kuszmaul
bradley at mit.edu
Thu Dec 18 19:15:28 PST 2014
I'd like to alert you to a problem that I found in linux libc. This bug
may affect users of jemalloc.
I've submitted a bug on libc as
https://sourceware.org/bugzilla/show_bug.cgi?id=17730
The problem is that under some conditions, libc allocates memory using
__libc_memalign or __libc_malloc and later frees it using free(), rather
than __libc_free(). This behavior is incorrect: for example, there is no
reason to believe that jemalloc will know what to do with
free(__libc_malloc(N)). It seems quite possible that the jemalloc data
structures could become corrupted, but I haven't investigated exactly what
happens.
One possible workaround for the problem is to arrange that if jemalloc sees
a pointer that it didn't create, then pass the pointer to the system's free
as
if (pointer_doesnt_belong_to_jemalloc(p)) {
void (*free_p)(void*) = (void(*)(void*)) (dlsym(RTLD_NEXT, "free"));
free_p(p);
}
this workaround *might* fix the problem for some users. I haven't got a
better idea except to fix libc.
The conditions are as follows:
Here are the conditions under which I can reproduce this problem:
* The main user code defines its own malloc/free
* The main user code dynamically loads a library using dlopen()/dlsym().
* The library contains thread-local storage.
* A thread runs, and then proceeds to touch the thread-local storage,
eventually invoking tls_get_addr_tail() (in /elf/dl-tls.c) and then
allocate_and_init() and then __libc_memalign().
* Eventually, this storage is deallocated using free() instead __libc_free().
I ran this on Fedora 20, but it looks like the problem is still there
in libc-main.
A test case is attached. This test case implements its own very
simple malloc/free library and complains if you pass free() an
improper pointer. You can run it as show below.
-Bradley
[bradley at 30-87-232 test]$ tar xfz libc-bug.tar.gz
[bradley at 30-87-232 test]$ cd libc-bug/
[bradley at 30-87-232 libc-bug]$ make check
gcc -g -W -Wall -Werror -pthread -fPIC --shared libtls.c -o libtls.so
cc -g -W -Wall -Werror -pthread -fPIC tls.c -ldl -o tls
./tls
malloc(32)=0x6020c0
malloc(46)=0x6020e0
malloc(1214)=0x60210e
malloc(46)=0x6025cc
malloc(56)=0x6025fa
malloc(96)=0x602632
malloc(288)=0x602692
malloc(288)=0x6027b2
malloc(288)=0x6028d2
malloc(288)=0x6029f2
1048576
1048576
1048576
malloc(288)=0x602b12
1048576
1048576
free passed 0xea1010 not in range
make: *** [check] Aborted (core dumped)
[bradley at 30-87-232 libc-bug]$
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://jemalloc.net/mailman/jemalloc-discuss/attachments/20141218/20b15fb7/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: libc-bug.tar.gz
Type: application/x-gzip
Size: 1691 bytes
Desc: not available
URL: <http://jemalloc.net/mailman/jemalloc-discuss/attachments/20141218/20b15fb7/attachment.bin>
More information about the jemalloc-discuss
mailing list