[glibc/f16] + - Drop lock before calling malloc_printerr (#757881)

Jeffrey Law law at fedoraproject.org
Tue Nov 29 18:23:27 UTC 2011


commit 2716093f61830255202455c2551969f848791136
Author: Jeff Law <law at redhat.com>
Date:   Tue Nov 29 11:23:08 2011 -0700

    +  - Drop lock before calling malloc_printerr (#757881)

 glibc-rh757881.patch |  170 ++++++++++++++++++++++++++++++++++++++++++++++++++
 glibc.spec           |    7 ++-
 2 files changed, 176 insertions(+), 1 deletions(-)
---
diff --git a/glibc-rh757881.patch b/glibc-rh757881.patch
new file mode 100644
index 0000000..0b41987
--- /dev/null
+++ b/glibc-rh757881.patch
@@ -0,0 +1,170 @@
+Index: glibc-2.12-2-gc4ccff1/malloc/arena.c
+===================================================================
+--- glibc-2.12-2-gc4ccff1.orig/malloc/arena.c
++++ glibc-2.12-2-gc4ccff1/malloc/arena.c
+@@ -870,7 +870,7 @@ heap_trim(heap, pad) heap_info *heap; si
+     heap = prev_heap;
+     if(!prev_inuse(p)) { /* consolidate backward */
+       p = prev_chunk(p);
+-      unlink(p, bck, fwd);
++      unlink(ar_ptr, p, bck, fwd);
+     }
+     assert(((unsigned long)((char*)p + new_size) & (pagesz-1)) == 0);
+     assert( ((char*)p + new_size) == ((char*)heap + heap->size) );
+Index: glibc-2.12-2-gc4ccff1/malloc/hooks.c
+===================================================================
+--- glibc-2.12-2-gc4ccff1.orig/malloc/hooks.c
++++ glibc-2.12-2-gc4ccff1/malloc/hooks.c
+@@ -219,7 +219,9 @@ top_check()
+ 	(char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem)))
+     return 0;
+ 
++  mutex_unlock(&main_arena);
+   malloc_printerr (check_action, "malloc: top chunk is corrupt", t);
++  mutex_lock(&main_arena);
+ 
+   /* Try to set up a new top chunk. */
+   brk = MORECORE(0);
+Index: glibc-2.12-2-gc4ccff1/malloc/malloc.c
+===================================================================
+--- glibc-2.12-2-gc4ccff1.orig/malloc/malloc.c
++++ glibc-2.12-2-gc4ccff1/malloc/malloc.c
+@@ -1541,12 +1541,14 @@
+ #define last(b)      ((b)->bk)
+ 
+ /* Take a chunk off a bin list */
+-#define unlink(P, BK, FD) {                                            \
++#define unlink(AV, P, BK, FD) {					       \
+   FD = P->fd;                                                          \
+   BK = P->bk;                                                          \
+-  if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                \
++  if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) {	       \
++    mutex_unlock(&(AV)->mutex);					       \
+     malloc_printerr (check_action, "corrupted double-linked list", P); \
+-  else {                                                               \
++    mutex_lock(&(AV)->mutex);					       \
++  } else {							       \
+     FD->bk = BK;                                                       \
+     BK->fd = FD;                                                       \
+     if (!in_smallbin_range (P->size)				       \
+@@ -2593,7 +2595,9 @@
+ 
+     else if (contiguous(av) && old_size && brk < old_end) {
+       /* Oops!  Someone else killed our space..  Can't touch anything.  */
++      mutex_unlock(&av->mutex);
+       malloc_printerr (3, "break adjusted to free malloc space", brk);
++      mutex_lock(&av->mutex);
+     }
+ 
+     /*
+@@ -3467,7 +3471,9 @@
+ 	{
+ 	  errstr = "malloc(): memory corruption (fast)";
+ 	errout:
++	  mutex_unlock(&av->mutex);
+ 	  malloc_printerr (check_action, errstr, chunk2mem (victim));
++	  mutex_lock(&av->mutex);
+ 	  return NULL;
+ 	}
+       check_remalloced_chunk(av, victim, nb);
+@@ -3552,8 +3558,12 @@
+       bck = victim->bk;
+       if (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0)
+ 	  || __builtin_expect (victim->size > av->system_mem, 0))
+-	malloc_printerr (check_action, "malloc(): memory corruption",
+-			 chunk2mem (victim));
++	{
++	  void *p = chunk2mem(victim);
++	  mutex_unlock(&av->mutex);
++	  malloc_printerr (check_action, "malloc(): memory corruption", p);
++	  mutex_lock(&av->mutex);
++	}
+       size = chunksize(victim);
+ 
+       /*
+@@ -3694,7 +3704,7 @@
+ 	  victim = victim->fd;
+ 
+ 	remainder_size = size - nb;
+-	unlink(victim, bck, fwd);
++	unlink(av, victim, bck, fwd);
+ 
+ 	/* Exhaust */
+ 	if (remainder_size < MINSIZE)  {
+@@ -3792,7 +3802,7 @@
+ 	remainder_size = size - nb;
+ 
+ 	/* unlink */
+-	unlink(victim, bck, fwd);
++	unlink(av, victim, bck, fwd);
+ 
+ 	/* Exhaust */
+ 	if (remainder_size < MINSIZE) {
+@@ -3927,9 +3937,11 @@
+     {
+       errstr = "free(): invalid pointer";
+     errout:
+-      if (! have_lock && locked)
++      if (have_lock || locked)
+ 	(void)mutex_unlock(&av->mutex);
+       malloc_printerr (check_action, errstr, chunk2mem(p));
++      if (have_lock)
++	mutex_lock(&av->mutex);
+       return;
+     }
+   /* We know that each chunk is at least MINSIZE bytes in size.  */
+@@ -4073,7 +4085,7 @@
+       prevsize = p->prev_size;
+       size += prevsize;
+       p = chunk_at_offset(p, -((long) prevsize));
+-      unlink(p, bck, fwd);
++      unlink(av, p, bck, fwd);
+     }
+ 
+     if (nextchunk != av->top) {
+@@ -4082,7 +4094,7 @@
+ 
+       /* consolidate forward */
+       if (!nextinuse) {
+-	unlink(nextchunk, bck, fwd);
++	unlink(av, nextchunk, bck, fwd);
+ 	size += nextsize;
+       } else
+ 	clear_inuse_bit_at_offset(nextchunk, 0);
+@@ -4243,7 +4255,7 @@
+ 	    prevsize = p->prev_size;
+ 	    size += prevsize;
+ 	    p = chunk_at_offset(p, -((long) prevsize));
+-	    unlink(p, bck, fwd);
++	    unlink(av, p, bck, fwd);
+ 	  }
+ 
+ 	  if (nextchunk != av->top) {
+@@ -4251,7 +4263,7 @@
+ 
+ 	    if (!nextinuse) {
+ 	      size += nextsize;
+-	      unlink(nextchunk, bck, fwd);
++	      unlink(av, nextchunk, bck, fwd);
+ 	    } else
+ 	      clear_inuse_bit_at_offset(nextchunk, 0);
+ 
+@@ -4320,7 +4332,9 @@
+     {
+       errstr = "realloc(): invalid old size";
+     errout:
++      mutex_unlock(&av->mutex);
+       malloc_printerr (check_action, errstr, chunk2mem(oldp));
++      mutex_lock(&av->mutex);
+       return NULL;
+     }
+ 
+@@ -4362,7 +4376,7 @@
+ 	     (unsigned long)(newsize = oldsize + nextsize) >=
+ 	     (unsigned long)(nb)) {
+       newp = oldp;
+-      unlink(next, bck, fwd);
++      unlink(av, next, bck, fwd);
+     }
+ 
+     /* allocate, copy, free */
diff --git a/glibc.spec b/glibc.spec
index 1495e71..fee2558 100644
--- a/glibc.spec
+++ b/glibc.spec
@@ -28,7 +28,7 @@
 Summary: The GNU libc libraries
 Name: glibc
 Version: %{glibcversion}
-Release: 19
+Release: 20
 # GPLv2+ is used in a bunch of programs, LGPLv2+ is used for libraries.
 # Things that are linked directly into dynamically linked programs
 # and shared libraries (e.g. crt files, lib*_nonshared.a) have an additional
@@ -45,6 +45,7 @@ Patch1: %{name}-ia64-lib64.patch
 Patch2: %{name}-no-leaf-attribute.patch
 Patch3: %{name}-localegrouping.patch
 Patch4: %{name}-arenalock.patch
+Patch5: %{name}-rh757881.patch
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Obsoletes: glibc-profile < 2.4
 Obsoletes: nss_db
@@ -266,6 +267,7 @@ rm -rf %{glibcportsdir}
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
+%patch5 -p1
 
 # A lot of programs still misuse memcpy when they have to use
 # memmove. The memcpy implementation below is not tolerant at
@@ -1118,6 +1120,9 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Mon Nov 28 2011 Jeff Law <law at redhat.com> - 2.14.90-20
+  - Drop lock before calling malloc_printerr (#757881)
+
 * Fri Nov 18 2011 Jeff Law <law at redhat.com> - 2.14.90-19
   - Check malloc arena atomically  (BZ#13071)
   - Don't call reused_arena when _int_new_arena failed (#753601)


More information about the scm-commits mailing list