Accepting request 311391 from home:Andreas_Schwab:Factory

- Add /usr/include/gnu/lib-names-.*.h to baselibs
- pthread-join-deadlock.patch: Don't require rtld lock to store static TLS
  offset in the DTV (bsc#930015, BZ #18457)
- heap-top-corruption.patch: Do not corrupt the top of a threaded heap if
  top chunk is MINSIZE (BZ #18502)

OBS-URL: https://build.opensuse.org/request/show/311391
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=405
This commit is contained in:
Andreas Schwab 2015-06-10 07:15:17 +00:00 committed by Git OBS Bridge
parent 5cdaa6fdff
commit f7b73d687a
9 changed files with 276 additions and 27 deletions

View File

@ -14,6 +14,7 @@ glibc-locale
glibc-devel
requires "glibc-<targettype> = %version"
arch i586 block!
+^/usr/include/gnu/lib-names-.*\.h$
+^/usr/include/gnu/stubs-.*\.h$
glibc-devel-static
arch i586 block!

View File

@ -1,3 +1,12 @@
-------------------------------------------------------------------
Tue Jun 9 08:16:46 UTC 2015 - schwab@suse.de
- Add /usr/include/gnu/lib-names-.*.h to baselibs
- pthread-join-deadlock.patch: Don't require rtld lock to store static TLS
offset in the DTV (bsc#930015, BZ #18457)
- heap-top-corruption.patch: Do not corrupt the top of a threaded heap if
top chunk is MINSIZE (BZ #18502)
-------------------------------------------------------------------
Wed Apr 8 12:50:39 UTC 2015 - mgorman@suse.com

View File

@ -245,6 +245,12 @@ Patch1004: powerpc-software-sqrt.patch
Patch1005: static-tls-dtv-limit.patch
# PATCH-FIX-UPSTREAM Fix regression in threaded application malloc performance (bsc#915955, BZ #17195)
Patch1006: threaded-trim-threshold.patch
# PATCH-FIX-UPSTREAM Simplify handling of nameserver configuration in resolver
Patch1007: resolv-nameserver-handling.patch
# PATCH-FIX-UPSTREAM Separate internal state between getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
Patch1008: nss-separate-state-getXXent.patch
# PATCH-FIX-UPSTREAM aarch64: Increase MINSIGSTKSZ and SIGSTKSZ (BZ #16850)
Patch1009: aarch64-sigstksz.patch
###
# Patches awaiting upstream approval
@ -259,12 +265,10 @@ Patch2003: abort-no-flush.patch
Patch2005: glibc-memset-nontemporal.diff
# PATCH-FIX-UPSTREAM Avoid redundant shift character in iconv output at block boundary (BZ #17197)
Patch2006: ibm93x-redundant-shift-si.patch
# PATCH-FIX-UPSTREAM Rewrite handling of nameserver configuration in resolver
Patch2007: resolv-nameserver-handling.patch
# PATCH-FIX-UPSTREAM Separate internal state between getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
Patch2008: nss-separate-state-getXXent.patch
# PATCH-FIX-UPSTREAM aarch64: Increase MINSIGSTKSZ and SIGSTKSZ (BZ #16850)
Patch2009: aarch64-sigstksz.patch
# PATCH-FIX-UPSTREAM Don't require rtld lock to store static TLS offset in the DTV (BZ #18457)
Patch2007: pthread-join-deadlock.patch
# PATCH-FIX-UPSTREAM malloc: Do not corrupt the top of a threaded heap if top chunk is MINSIZE (BZ #18502)
Patch2008: heap-top-corruption.patch
# Non-glibc patches
# PATCH-FIX-OPENSUSE Remove debianisms from manpages
@ -472,6 +476,9 @@ rm nscd/s-stamp
%patch1004 -p1
%patch1005 -p1
%patch1006 -p1
%patch1007 -p1
%patch1008 -p1
%patch1009 -p1
%patch2000 -p1
%patch2002 -p1
@ -480,7 +487,6 @@ rm nscd/s-stamp
%patch2006 -p1
%patch2007 -p1
%patch2008 -p1
%patch2009 -p1
%patch3000
@ -920,8 +926,8 @@ touch %{buildroot}/run/nscd/{socket,nscd.pid}
# Create ld.so.conf
#
cat > %{buildroot}/etc/ld.so.conf <<EOF
%if "%{_lib}" == "lib64"
/usr/local/lib64
%if "%{_lib}" != "lib"
/usr/local/%{_lib}
%endif
%ifarch ppc
/usr/local/lib64

View File

@ -1,3 +1,12 @@
-------------------------------------------------------------------
Tue Jun 9 08:16:46 UTC 2015 - schwab@suse.de
- Add /usr/include/gnu/lib-names-.*.h to baselibs
- pthread-join-deadlock.patch: Don't require rtld lock to store static TLS
offset in the DTV (bsc#930015, BZ #18457)
- heap-top-corruption.patch: Do not corrupt the top of a threaded heap if
top chunk is MINSIZE (BZ #18502)
-------------------------------------------------------------------
Wed Apr 8 12:50:39 UTC 2015 - mgorman@suse.com

View File

@ -244,6 +244,12 @@ Patch1004: powerpc-software-sqrt.patch
Patch1005: static-tls-dtv-limit.patch
# PATCH-FIX-UPSTREAM Fix regression in threaded application malloc performance (bsc#915955, BZ #17195)
Patch1006: threaded-trim-threshold.patch
# PATCH-FIX-UPSTREAM Simplify handling of nameserver configuration in resolver
Patch1007: resolv-nameserver-handling.patch
# PATCH-FIX-UPSTREAM Separate internal state between getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
Patch1008: nss-separate-state-getXXent.patch
# PATCH-FIX-UPSTREAM aarch64: Increase MINSIGSTKSZ and SIGSTKSZ (BZ #16850)
Patch1009: aarch64-sigstksz.patch
###
# Patches awaiting upstream approval
@ -258,12 +264,10 @@ Patch2003: abort-no-flush.patch
Patch2005: glibc-memset-nontemporal.diff
# PATCH-FIX-UPSTREAM Avoid redundant shift character in iconv output at block boundary (BZ #17197)
Patch2006: ibm93x-redundant-shift-si.patch
# PATCH-FIX-UPSTREAM Rewrite handling of nameserver configuration in resolver
Patch2007: resolv-nameserver-handling.patch
# PATCH-FIX-UPSTREAM Separate internal state between getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
Patch2008: nss-separate-state-getXXent.patch
# PATCH-FIX-UPSTREAM aarch64: Increase MINSIGSTKSZ and SIGSTKSZ (BZ #16850)
Patch2009: aarch64-sigstksz.patch
# PATCH-FIX-UPSTREAM Don't require rtld lock to store static TLS offset in the DTV (BZ #18457)
Patch2007: pthread-join-deadlock.patch
# PATCH-FIX-UPSTREAM malloc: Do not corrupt the top of a threaded heap if top chunk is MINSIZE (BZ #18502)
Patch2008: heap-top-corruption.patch
# Non-glibc patches
# PATCH-FIX-OPENSUSE Remove debianisms from manpages
@ -472,6 +476,9 @@ rm nscd/s-stamp
%patch1004 -p1
%patch1005 -p1
%patch1006 -p1
%patch1007 -p1
%patch1008 -p1
%patch1009 -p1
%patch2000 -p1
%patch2002 -p1
@ -480,7 +487,6 @@ rm nscd/s-stamp
%patch2006 -p1
%patch2007 -p1
%patch2008 -p1
%patch2009 -p1
%patch3000
@ -920,8 +926,8 @@ touch %{buildroot}/run/nscd/{socket,nscd.pid}
# Create ld.so.conf
#
cat > %{buildroot}/etc/ld.so.conf <<EOF
%if "%{_lib}" == "lib64"
/usr/local/lib64
%if "%{_lib}" != "lib"
/usr/local/%{_lib}
%endif
%ifarch ppc
/usr/local/lib64

View File

@ -1,3 +1,12 @@
-------------------------------------------------------------------
Tue Jun 9 08:16:46 UTC 2015 - schwab@suse.de
- Add /usr/include/gnu/lib-names-.*.h to baselibs
- pthread-join-deadlock.patch: Don't require rtld lock to store static TLS
offset in the DTV (bsc#930015, BZ #18457)
- heap-top-corruption.patch: Do not corrupt the top of a threaded heap if
top chunk is MINSIZE (BZ #18502)
-------------------------------------------------------------------
Wed Apr 8 12:50:39 UTC 2015 - mgorman@suse.com

View File

@ -245,6 +245,12 @@ Patch1004: powerpc-software-sqrt.patch
Patch1005: static-tls-dtv-limit.patch
# PATCH-FIX-UPSTREAM Fix regression in threaded application malloc performance (bsc#915955, BZ #17195)
Patch1006: threaded-trim-threshold.patch
# PATCH-FIX-UPSTREAM Simplify handling of nameserver configuration in resolver
Patch1007: resolv-nameserver-handling.patch
# PATCH-FIX-UPSTREAM Separate internal state between getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
Patch1008: nss-separate-state-getXXent.patch
# PATCH-FIX-UPSTREAM aarch64: Increase MINSIGSTKSZ and SIGSTKSZ (BZ #16850)
Patch1009: aarch64-sigstksz.patch
###
# Patches awaiting upstream approval
@ -259,12 +265,10 @@ Patch2003: abort-no-flush.patch
Patch2005: glibc-memset-nontemporal.diff
# PATCH-FIX-UPSTREAM Avoid redundant shift character in iconv output at block boundary (BZ #17197)
Patch2006: ibm93x-redundant-shift-si.patch
# PATCH-FIX-UPSTREAM Rewrite handling of nameserver configuration in resolver
Patch2007: resolv-nameserver-handling.patch
# PATCH-FIX-UPSTREAM Separate internal state between getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
Patch2008: nss-separate-state-getXXent.patch
# PATCH-FIX-UPSTREAM aarch64: Increase MINSIGSTKSZ and SIGSTKSZ (BZ #16850)
Patch2009: aarch64-sigstksz.patch
# PATCH-FIX-UPSTREAM Don't require rtld lock to store static TLS offset in the DTV (BZ #18457)
Patch2007: pthread-join-deadlock.patch
# PATCH-FIX-UPSTREAM malloc: Do not corrupt the top of a threaded heap if top chunk is MINSIZE (BZ #18502)
Patch2008: heap-top-corruption.patch
# Non-glibc patches
# PATCH-FIX-OPENSUSE Remove debianisms from manpages
@ -472,6 +476,9 @@ rm nscd/s-stamp
%patch1004 -p1
%patch1005 -p1
%patch1006 -p1
%patch1007 -p1
%patch1008 -p1
%patch1009 -p1
%patch2000 -p1
%patch2002 -p1
@ -480,7 +487,6 @@ rm nscd/s-stamp
%patch2006 -p1
%patch2007 -p1
%patch2008 -p1
%patch2009 -p1
%patch3000
@ -920,8 +926,8 @@ touch %{buildroot}/run/nscd/{socket,nscd.pid}
# Create ld.so.conf
#
cat > %{buildroot}/etc/ld.so.conf <<EOF
%if "%{_lib}" == "lib64"
/usr/local/lib64
%if "%{_lib}" != "lib"
/usr/local/%{_lib}
%endif
%ifarch ppc
/usr/local/lib64

51
heap-top-corruption.patch Normal file
View File

@ -0,0 +1,51 @@
From: Mel Gorman <mgorman@suse.de>
Subject: [PATCH] [v3] malloc: Do not corrupt the top of a threaded heap if
top chunk is MINSIZE [BZ #18502]
Date: Mon, 8 Jun 2015 13:36:13 +0100
mksquashfs was reported in openSUSE to be causing segmentation faults when
creating installation images. Testing showed that mksquashfs sometimes
failed and could be reproduced within 10 attempts. The core dump looked
like the heap top was corrupted and was pointing to an unmapped area. In
other cases, this has been due to an application corrupting glibc structures
but mksquashfs appears to be fine in this regard.
The problem is that heap_trim is "growing" the top into unmapped space.
If the top chunk == MINSIZE then top_area is -1 and this check does not
behave as expected due to a signed/unsigned comparison
if (top_area <= pad)
return 0;
The next calculation extra = ALIGN_DOWN(top_area - pad, pagesz) calculates
extra as a negative number which also is unnoticed due to a signed/unsigned
comparison. We then call shrink_heap(heap, negative_number) which crashes
later. This patch adds a simple check against MINSIZE to make sure extra
does not become negative. It adds a cast to hint to the reader that this
is a signed vs unsigned issue.
Without the patch, mksquash fails within 10 attempts. With it applied, it
completed 1000 times without error. The standard test suite "make check"
showed no changes in the summary of test results.
2015-06-08 Mel Gorman <mgorman@suse.de>
[BZ #18502]
* malloc/arena.c: Avoid corruption of the top of heaps for threads
---
malloc/arena.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: glibc-2.21/malloc/arena.c
===================================================================
--- glibc-2.21.orig/malloc/arena.c
+++ glibc-2.21/malloc/arena.c
@@ -699,7 +699,7 @@ heap_trim (heap_info *heap, size_t pad)
by preserving the top pad and at least a page. */
top_size = chunksize (top_chunk);
top_area = top_size - MINSIZE - 1;
- if (top_area <= pad)
+ if (top_area < 0 || (size_t) top_area <= pad)
return 0;
extra = ALIGN_DOWN(top_area - pad, pagesz);

152
pthread-join-deadlock.patch Normal file
View File

@ -0,0 +1,152 @@
[PR dynamic-link/18457]
* elf/dl-tls.c (tls_get_addr_tail): Don't take the rtld lock
if we already have a final static TLS offset.
* nptl/tst-join7.c, nptl/tst-join7mod.c: New.
Index: glibc-2.21/elf/dl-tls.c
===================================================================
--- glibc-2.21.orig/elf/dl-tls.c
+++ glibc-2.21/elf/dl-tls.c
@@ -755,30 +755,44 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t
the_map = listp->slotinfo[idx].map;
}
- /* Make sure that, if a dlopen running in parallel forces the
- variable into static storage, we'll wait until the address in the
- static TLS block is set up, and use that. If we're undecided
- yet, make sure we make the decision holding the lock as well. */
- if (__glibc_unlikely (the_map->l_tls_offset
- != FORCED_DYNAMIC_TLS_OFFSET))
+ /* If the TLS block for the map is already assigned to dynamic or to
+ static TLS, avoid the lock. Be careful to use the same value for
+ both tests; if we reloaded it, the second test might mistake
+ forced dynamic for an offset. Now, if the decision hasn't been
+ made, take the rtld lock, so that an ongoing dlopen gets a chance
+ to complete, and then retest; if the decision is still pending,
+ force the module to dynamic TLS. */
+ ptrdiff_t offset = atomic_load_relaxed (&the_map->l_tls_offset);
+ if (__glibc_unlikely (offset != FORCED_DYNAMIC_TLS_OFFSET))
{
+ if (__glibc_unlikely (offset != NO_TLS_OFFSET))
+ goto static_tls;
__rtld_lock_lock_recursive (GL(dl_load_lock));
- if (__glibc_likely (the_map->l_tls_offset == NO_TLS_OFFSET))
+ offset = the_map->l_tls_offset;
+ if (__glibc_likely (offset == NO_TLS_OFFSET))
{
the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET;
__rtld_lock_unlock_recursive (GL(dl_load_lock));
}
- else if (__glibc_likely (the_map->l_tls_offset
- != FORCED_DYNAMIC_TLS_OFFSET))
+ else if (__glibc_likely (offset != FORCED_DYNAMIC_TLS_OFFSET))
{
+ /* The decision is made, and it is final. We use the value
+ we've already loaded, but we could even load the offset
+ after releasing the lock, since it won't change. Should
+ the module be released while another thread references
+ one of its TLS variables, that's undefined behavior. */
+ __rtld_lock_unlock_recursive (GL(dl_load_lock));
+
+ static_tls:
+ ;
+
#if TLS_TCB_AT_TP
- void *p = (char *) THREAD_SELF - the_map->l_tls_offset;
+ void *p = (char *) THREAD_SELF - offset;
#elif TLS_DTV_AT_TP
- void *p = (char *) THREAD_SELF + the_map->l_tls_offset + TLS_PRE_TCB_SIZE;
+ void *p = (char *) THREAD_SELF + offset + TLS_PRE_TCB_SIZE;
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
- __rtld_lock_unlock_recursive (GL(dl_load_lock));
dtv[GET_ADDR_MODULE].pointer.is_static = true;
dtv[GET_ADDR_MODULE].pointer.val = p;
Index: glibc-2.21/nptl/Makefile
===================================================================
--- glibc-2.21.orig/nptl/Makefile
+++ glibc-2.21/nptl/Makefile
@@ -234,7 +234,7 @@ tests = tst-typesizes \
tst-basic7 \
tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \
tst-raise1 \
- tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 \
+ tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 tst-join7 \
tst-detach1 \
tst-eintr1 tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \
tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 tst-tsd6 \
@@ -312,7 +312,8 @@ endif
modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
- tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod
+ tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
+ tst-join7mod
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o
test-extras += $(modules-names) tst-cleanup4aux
test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
@@ -517,6 +518,11 @@ $(objpfx)tst-tls6.out: tst-tls6.sh $(obj
$(evaluate-test)
endif
+$(objpfx)tst-join7: $(libdl) $(shared-thread-library)
+$(objpfx)tst-join7.out: $(objpfx)tst-join7mod.so
+$(objpfx)tst-join7mod.so: $(shared-thread-library)
+LDFLAGS-tst-join7mod.so = -Wl,-soname,tst-join7mod.so
+
$(objpfx)tst-dlsym1: $(libdl) $(shared-thread-library)
$(objpfx)tst-fini1: $(shared-thread-library) $(objpfx)tst-fini1mod.so
Index: glibc-2.21/nptl/tst-join7.c
===================================================================
--- /dev/null
+++ glibc-2.21/nptl/tst-join7.c
@@ -0,0 +1,12 @@
+#include <dlfcn.h>
+
+int
+do_test (void)
+{
+ void *f = dlopen ("tst-join7mod.so", RTLD_NOW | RTLD_GLOBAL);
+ if (f) dlclose (f); else return 1;
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Index: glibc-2.21/nptl/tst-join7mod.c
===================================================================
--- /dev/null
+++ glibc-2.21/nptl/tst-join7mod.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <pthread.h>
+
+static pthread_t th;
+static int running = 1;
+
+static void *
+test_run (void *p)
+{
+ while (running)
+ fprintf (stderr, "XXX test_run\n");
+ fprintf (stderr, "XXX test_run FINISHED\n");
+ return NULL;
+}
+
+static void __attribute__ ((constructor))
+do_init (void)
+{
+ pthread_create (&th, NULL, test_run, NULL);
+}
+
+static void __attribute__ ((destructor))
+do_end (void)
+{
+ running = 0;
+ fprintf (stderr, "thread_join...\n");
+ pthread_join (th, NULL);
+ fprintf (stderr, "thread_join DONE\n");
+}