NetBSD-Bugs archive

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

Re: lib/42876: realloc crash with threads



> >Number:         42876
> >Category:       lib
> >Synopsis:       realloc crash with threads
> >Confidential:   no
> >Severity:       serious

Please try this.  Trying to remove the node after mremap is too late.

enami.

Index: jemalloc.c
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/jemalloc.c,v
retrieving revision 1.20
diff -u -r1.20 jemalloc.c
--- jemalloc.c  12 Feb 2009 03:11:01 -0000      1.20
+++ jemalloc.c  2 Mar 2010 22:57:59 -0000
@@ -2856,25 +2856,30 @@
                        /* size_t wrap-around */
                        return (NULL);
                }
+
+               malloc_mutex_lock(&chunks_mtx);
+               key.chunk = __DECONST(void *, ptr);
+               /* LINTED */
+               node = RB_FIND(chunk_tree_s, &huge, &key);
+               assert(node != NULL);
+               assert(node->chunk == ptr);
+               assert(node->size == oldcsize);
+               RB_REMOVE(chunk_tree_s, &huge, node);
+               malloc_mutex_unlock(&chunks_mtx);
                newptr = mremap(ptr, oldcsize, NULL, newcsize,
                    MAP_ALIGNED(chunksize_2pow));
-               if (newptr != MAP_FAILED) {
+               if (newptr == MAP_FAILED) {
+                       malloc_mutex_lock(&chunks_mtx);
+                       RB_INSERT(chunk_tree_s, &huge, node);
+                       malloc_mutex_unlock(&chunks_mtx);
+               } else {
                        assert(CHUNK_ADDR2BASE(newptr) == newptr);
 
                        /* update tree */
                        malloc_mutex_lock(&chunks_mtx);
-                       key.chunk = __DECONST(void *, ptr);
-                       /* LINTED */
-                       node = RB_FIND(chunk_tree_s, &huge, &key);
-                       assert(node != NULL);
-                       assert(node->chunk == ptr);
-                       assert(node->size == oldcsize);
                        node->size = newcsize;
-                       if (ptr != newptr) {
-                               RB_REMOVE(chunk_tree_s, &huge, node);
-                               node->chunk = newptr;
-                               RB_INSERT(chunk_tree_s, &huge, node);
-                       }
+                       node->chunk = newptr;
+                       RB_INSERT(chunk_tree_s, &huge, node);
 #ifdef MALLOC_STATS
                        huge_nralloc++;
                        huge_allocated += newcsize - oldcsize;


Home | Main Index | Thread Index | Old Index