Missing return in malloc.c:arena_dalloc?

Ryan Stone rysto32 at gmail.com
Tue Jan 26 21:34:53 UTC 2010


I think that there is a bug in the magazine allocator in jemalloc that
can cause a segfault in certain rare conditions.  It looks to me like
a return is missing:

*** malloc.c    (revision 203047)
--- malloc.c    (working copy)
***************
*** 3793,3812 ****
--- 3793,3813 ----
  #ifdef MALLOC_MAG
                if (__isthreaded && opt_mag) {
                        mag_rack_t *rack = mag_rack;
                        if (rack == NULL) {
                                rack = mag_rack_create(arena);
                                if (rack == NULL) {
                                        malloc_spin_lock(&arena->lock);
                                        arena_dalloc_small(arena, chunk, ptr,
                                            mapelm);
                                        malloc_spin_unlock(&arena->lock);
+                                       return;
                                }
                                mag_rack = rack;
                        }
                        mag_rack_dalloc(rack, ptr);
                } else {
  #endif
                        malloc_spin_lock(&arena->lock);
                        arena_dalloc_small(arena, chunk, ptr, mapelm);
                        malloc_spin_unlock(&arena->lock);
  #ifdef MALLOC_MAG

The logic here seems to be, "if the magazine option is enabled, try to
get the magazine rack out of the TLS variable mag_rack.  If we haven't
yet allocated a rack for this thread, try to create one with
mag_rack_create.  If we fail to allocate the rack, then free the
memory directly to the arena.  Currently, after freeing to the arena
the code falls-through and tries to free the memory to a NULL rack,
which can't possibly be right.  mag_rack_dalloc definitely can't
handle a NULL rack.  It seems to me that the intent here is to return
after calling arena_dalloc_small?  There's a similar case in
mag_rack_dalloc where it tries to allocate a magazine, and if it
fails, it calls arena_dalloc_small and then returns.

Note that gmail has mangled the tabs in the diff I pasted above, so
I'm attaching a correct version as a patch.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: malloc.diff
Type: application/octet-stream
Size: 776 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-current/attachments/20100126/7c2a7d6f/malloc.obj


More information about the freebsd-current mailing list