<div dir="ltr">I'd like to alert you to a problem that I found in linux libc. This bug may affect users of jemalloc.<div><br></div><div>I've submitted a bug on libc as<br><div> <a href="https://sourceware.org/bugzilla/show_bug.cgi?id=17730">https://sourceware.org/bugzilla/show_bug.cgi?id=17730</a><br></div></div><div><br></div><div>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.</div><div><br></div><div>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</div><div><br></div><div> if (pointer_doesnt_belong_to_jemalloc(p)) {</div><div> void (*free_p)(void*) = (void(*)(void*)) (dlsym(RTLD_NEXT, "free"));</div><div> free_p(p);</div><div> }</div><div><br></div><div>this workaround *might* fix the problem for some users. I haven't got a better idea except to fix libc.</div><div> </div><div><br></div><div>The conditions are as follows:</div><div><pre class="" id="comment_text_0" style="white-space:pre-wrap;width:50em;color:rgb(0,0,0)"><font face="arial, helvetica, sans-serif">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().</font></pre><pre class="" id="comment_text_0" style="white-space:pre-wrap;width:50em;color:rgb(0,0,0)"><font face="arial, helvetica, sans-serif">I ran this on Fedora 20, but it looks like the problem is still there in libc-main. </font></pre><pre class="" id="comment_text_0" style="white-space:pre-wrap;width:50em;color:rgb(0,0,0)"><span style="font-family:arial,helvetica,sans-serif">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.</span><br></pre><pre class="" id="comment_text_0" style="white-space:pre-wrap;width:50em;color:rgb(0,0,0)">-Bradley</pre><pre class="" id="comment_text_0" style="white-space:pre-wrap;width:50em;color:rgb(0,0,0)"><pre class="" id="comment_text_0" style="font-size:medium;white-space:pre-wrap;width:50em">[bradley@30-87-232 test]$ tar xfz libc-bug.tar.gz
[bradley@30-87-232 test]$ cd libc-bug/
[bradley@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@30-87-232 libc-bug]$</pre></pre></div></div>