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 - 2.14.90-20 + - Drop lock before calling malloc_printerr (#757881) + * Fri Nov 18 2011 Jeff Law - 2.14.90-19 - Check malloc arena atomically (BZ#13071) - Don't call reused_arena when _int_new_arena failed (#753601)