diff --git a/glibc-rh789238.patch b/glibc-rh789238.patch new file mode 100644 index 0000000..1801123 --- /dev/null +++ b/glibc-rh789238.patch @@ -0,0 +1,115 @@ +Only in b/malloc: arena.c.orig +Only in b/malloc: hooks.c.orig +diff -rup a/malloc/malloc.c b/malloc/malloc.c +--- a/malloc/malloc.c 2012-02-14 10:08:22.062534892 -0700 ++++ b/malloc/malloc.c 2012-02-14 10:19:43.088724473 -0700 +@@ -2936,8 +2936,9 @@ public_mALLOc(size_t bytes) + (void)mutex_unlock(&ar_ptr->mutex); + } else { + /* ... or sbrk() has failed and there is still a chance to mmap() */ +- ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); +- (void)mutex_unlock(&main_arena.mutex); ++ mstate prev = ar_ptr->next ? ar_ptr : 0; ++ (void)mutex_unlock(&ar_ptr->mutex); ++ ar_ptr = arena_get2(prev, bytes); + if(ar_ptr) { + victim = _int_malloc(ar_ptr, bytes); + (void)mutex_unlock(&ar_ptr->mutex); +@@ -3151,23 +3152,26 @@ public_vALLOc(size_t bytes) + if(!ar_ptr) + return 0; + p = _int_valloc(ar_ptr, bytes); +- (void)mutex_unlock(&ar_ptr->mutex); + if(!p) { + /* Maybe the failure is due to running out of mmapped areas. */ + if(ar_ptr != &main_arena) { ++ (void)mutex_unlock(&ar_ptr->mutex); + ar_ptr = &main_arena; + (void)mutex_lock(&ar_ptr->mutex); + p = _int_memalign(ar_ptr, pagesz, bytes); + (void)mutex_unlock(&ar_ptr->mutex); + } else { + /* ... or sbrk() has failed and there is still a chance to mmap() */ +- ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); ++ mstate prev = ar_ptr->next ? ar_ptr : 0; ++ (void)mutex_unlock(&ar_ptr->mutex); ++ ar_ptr = arena_get2(prev, bytes); + if(ar_ptr) { + p = _int_memalign(ar_ptr, pagesz, bytes); + (void)mutex_unlock(&ar_ptr->mutex); + } + } +- } ++ } else ++ (void)mutex_unlock(&ar_ptr->mutex); + assert(!p || chunk_is_mmapped(mem2chunk(p)) || + ar_ptr == arena_for_chunk(mem2chunk(p))); + +@@ -3195,24 +3199,26 @@ public_pVALLOc(size_t bytes) + + arena_get(ar_ptr, bytes + 2*pagesz + MINSIZE); + p = _int_pvalloc(ar_ptr, bytes); +- (void)mutex_unlock(&ar_ptr->mutex); + if(!p) { + /* Maybe the failure is due to running out of mmapped areas. */ + if(ar_ptr != &main_arena) { ++ (void)mutex_unlock(&ar_ptr->mutex); + ar_ptr = &main_arena; + (void)mutex_lock(&ar_ptr->mutex); + p = _int_memalign(ar_ptr, pagesz, rounded_bytes); + (void)mutex_unlock(&ar_ptr->mutex); + } else { + /* ... or sbrk() has failed and there is still a chance to mmap() */ +- ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, +- bytes + 2*pagesz + MINSIZE); ++ mstate prev = ar_ptr->next ? ar_ptr : 0; ++ (void)mutex_unlock(&ar_ptr->mutex); ++ ar_ptr = arena_get2(prev, bytes + 2*pagesz + MINSIZE); + if(ar_ptr) { + p = _int_memalign(ar_ptr, pagesz, rounded_bytes); + (void)mutex_unlock(&ar_ptr->mutex); + } + } +- } ++ } else ++ (void)mutex_unlock(&ar_ptr->mutex); + assert(!p || chunk_is_mmapped(mem2chunk(p)) || + ar_ptr == arena_for_chunk(mem2chunk(p))); + +@@ -3277,8 +3283,6 @@ public_cALLOc(size_t n, size_t elem_size + #endif + mem = _int_malloc(av, sz); + +- /* Only clearing follows, so we can unlock early. */ +- (void)mutex_unlock(&av->mutex); + + assert(!mem || chunk_is_mmapped(mem2chunk(mem)) || + av == arena_for_chunk(mem2chunk(mem))); +@@ -3286,21 +3290,23 @@ public_cALLOc(size_t n, size_t elem_size + if (mem == 0) { + /* Maybe the failure is due to running out of mmapped areas. */ + if(av != &main_arena) { ++ (void)mutex_unlock(&av->mutex); + (void)mutex_lock(&main_arena.mutex); + mem = _int_malloc(&main_arena, sz); + (void)mutex_unlock(&main_arena.mutex); + } else { + /* ... or sbrk() has failed and there is still a chance to mmap() */ +- (void)mutex_lock(&main_arena.mutex); +- av = arena_get2(av->next ? av : 0, sz); +- (void)mutex_unlock(&main_arena.mutex); ++ mstate prev = av->next ? av : 0; ++ (void)mutex_unlock(&av->mutex); ++ av = arena_get2(prev, sz); + if(av) { + mem = _int_malloc(av, sz); + (void)mutex_unlock(&av->mutex); + } + } + if (mem == 0) return 0; +- } ++ } else ++ (void)mutex_unlock(&av->mutex); + p = mem2chunk(mem); + + /* Two optional cases in which clearing not necessary */ diff --git a/glibc.spec b/glibc.spec index effaadf..1dad96f 100644 --- a/glibc.spec +++ b/glibc.spec @@ -28,7 +28,7 @@ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 21%{?dist} +Release: 22%{?dist} # 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 @@ -96,6 +96,8 @@ Patch30: %{name}-rh791161.patch Patch31 : %{name}-rh697149.patch # Submitted upstream BZ 9954 Patch32 : %{name}-rh739743.patch +# Discussion started upstream, patch needs to be submitted +Patch33 : %{name}-rh789238.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -347,6 +349,7 @@ rm -rf %{glibcportsdir} %patch30 -p1 %patch31 -p1 %patch32 -p1 +%patch33 -p1 # A lot of programs still misuse memcpy when they have to use # memmove. The memcpy implementation below is not tolerant at @@ -1199,6 +1202,9 @@ rm -f *.filelist* %endif %changelog +* Mon Feb 20 2012 Jeff Law - 2.15-22 + - Fix main arena locking in malloc/calloc retry path (#789238) + * Fri Feb 17 2012 Jeff Law - 2.15-21 - Correctly identify all 127.x.y.z addresses (#739743) - Don't assign native result if result has no associated interface (#739743)