patches/uClibc/0.9.30.2/270-malloc-fix-race-condition-and-other-bugs-in-the-no-m.patch
changeset 1819 66fcfb3d6745
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/patches/uClibc/0.9.30.2/270-malloc-fix-race-condition-and-other-bugs-in-the-no-m.patch	Sun Feb 28 11:50:15 2010 +0100
     1.3 @@ -0,0 +1,89 @@
     1.4 +From fa476d01f1c1990a92ee49d1f1c557b83805d0e9 Mon Sep 17 00:00:00 2001
     1.5 +From: Freeman Wang <xwang@ubicom.com>
     1.6 +Date: Sat, 19 Dec 2009 13:43:00 -0800
     1.7 +Subject: [PATCH 09/15] malloc: fix race condition and other bugs in the no-mmu malloc
     1.8 +
     1.9 +Fixes multiple race conditions on mmb list. This was done by
    1.10 +making the mmb_heap_lock into a recursive lock and making the
    1.11 +regular heap_lock extend to cover the mmb heap handling.
    1.12 +
    1.13 +Also move the new_mmb allocation up to before the mmb list is
    1.14 +iterated through to find the insertion point. When the mmb_heap
    1.15 +also runs out and needs to be extended when the regular heap is
    1.16 +just extended, the mmb list could be messed up.
    1.17 +
    1.18 +Signed-off-by: Freeman Wang <xwang@ubicom.com>
    1.19 +Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
    1.20 +---
    1.21 + libc/stdlib/malloc/free.c   |    6 +++---
    1.22 + libc/stdlib/malloc/malloc.c |    7 ++++---
    1.23 + 2 files changed, 7 insertions(+), 6 deletions(-)
    1.24 +
    1.25 +diff --git a/libc/stdlib/malloc/free.c b/libc/stdlib/malloc/free.c
    1.26 +index 90e18f4..741248a 100644
    1.27 +--- a/libc/stdlib/malloc/free.c
    1.28 ++++ b/libc/stdlib/malloc/free.c
    1.29 +@@ -179,14 +179,14 @@ __free_to_heap (void *mem, struct heap_free_area **heap
    1.30 + 	      /* Start searching again from the end of this block.  */
    1.31 + 	      start = mmb_end;
    1.32 + 
    1.33 ++	      /* Release the descriptor block we used.  */
    1.34 ++	      free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
    1.35 ++
    1.36 + 	      /* We have to unlock the heap before we recurse to free the mmb
    1.37 + 		 descriptor, because we might be unmapping from the mmb
    1.38 + 		 heap.  */
    1.39 +               __heap_unlock (heap_lock);
    1.40 + 
    1.41 +-	      /* Release the descriptor block we used.  */
    1.42 +-	      free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
    1.43 +-
    1.44 + 	      /* Do the actual munmap.  */
    1.45 + 	      munmap ((void *)mmb_start, mmb_end - mmb_start);
    1.46 + 
    1.47 +diff --git a/libc/stdlib/malloc/malloc.c b/libc/stdlib/malloc/malloc.c
    1.48 +index 71f9e58..84a6acd 100644
    1.49 +--- a/libc/stdlib/malloc/malloc.c
    1.50 ++++ b/libc/stdlib/malloc/malloc.c
    1.51 +@@ -48,7 +48,7 @@ struct malloc_mmb *__malloc_mmapped_blocks = 0;
    1.52 + HEAP_DECLARE_STATIC_FREE_AREA (initial_mmb_fa, 48); /* enough for 3 mmbs */
    1.53 + struct heap_free_area *__malloc_mmb_heap = HEAP_INIT_WITH_FA (initial_mmb_fa);
    1.54 + #ifdef HEAP_USE_LOCKING
    1.55 +-pthread_mutex_t __malloc_mmb_heap_lock = PTHREAD_MUTEX_INITIALIZER;
    1.56 ++pthread_mutex_t __malloc_mmb_heap_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
    1.57 + #endif
    1.58 + #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
    1.59 + 
    1.60 +@@ -151,19 +151,19 @@ __malloc_from_heap (size_t size, struct heap_free_area **heap
    1.61 + 	  /* Try again to allocate.  */
    1.62 + 	  mem = __heap_alloc (heap, &size);
    1.63 + 
    1.64 +-	  __heap_unlock (heap_lock);
    1.65 + 
    1.66 + #if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__)
    1.67 + 	  /* Insert a record of BLOCK in sorted order into the
    1.68 + 	     __malloc_mmapped_blocks list.  */
    1.69 + 
    1.70 ++	  new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
    1.71 ++
    1.72 + 	  for (prev_mmb = 0, mmb = __malloc_mmapped_blocks;
    1.73 + 	       mmb;
    1.74 + 	       prev_mmb = mmb, mmb = mmb->next)
    1.75 + 	    if (block < mmb->mem)
    1.76 + 	      break;
    1.77 + 
    1.78 +-	  new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
    1.79 + 	  new_mmb->next = mmb;
    1.80 + 	  new_mmb->mem = block;
    1.81 + 	  new_mmb->size = block_size;
    1.82 +@@ -177,6 +177,7 @@ __malloc_from_heap (size_t size, struct heap_free_area **heap
    1.83 + 			    (unsigned)new_mmb,
    1.84 + 			    (unsigned)new_mmb->mem, block_size);
    1.85 + #endif /* !MALLOC_USE_SBRK && __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
    1.86 ++	  __heap_unlock (heap_lock);
    1.87 + 	}
    1.88 +     }
    1.89 + 
    1.90 +-- 
    1.91 +1.6.6.1
    1.92 +