diff --git a/catopen-unbound-alloca.patch b/catopen-unbound-alloca.patch new file mode 100644 index 0000000..fbfd278 --- /dev/null +++ b/catopen-unbound-alloca.patch @@ -0,0 +1,219 @@ +2015-08-08 Paul Pluzhnikov + + [BZ #17905] + * catgets/Makefile (tst-catgets-mem): New test. + * catgets/catgets.c (catopen): Don't use unbounded alloca. + * catgets/open_catalog.c (__open_catalog): Likewise. + * catgets/tst-catgets.c (do_bz17905): Test unbounded alloca. + +Index: glibc-2.22/catgets/Makefile +=================================================================== +--- glibc-2.22.orig/catgets/Makefile ++++ glibc-2.22/catgets/Makefile +@@ -34,6 +34,7 @@ test-srcs = test-gencat + ifeq ($(run-built-tests),yes) + tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \ + $(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out ++tests-special += $(objpfx)tst-catgets-mem.out + endif + + gencat-modules = xmalloc +@@ -50,9 +51,11 @@ catgets-CPPFLAGS := -DNLSPATH='"$(msgcat + + generated += de.msg test1.cat test1.h test2.cat test2.h sample.SJIS.cat \ + test-gencat.h ++generated += tst-catgets.mtrace tst-catgets-mem.out ++ + generated-dirs += de + +-tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de ++tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de MALLOC_TRACE=$(objpfx)tst-catgets.mtrace + + ifeq ($(run-built-tests),yes) + # This test just checks whether the program produces any error or not. +@@ -86,4 +89,8 @@ $(objpfx)test-gencat.out: test-gencat.sh + $(objpfx)sample.SJIS.cat: sample.SJIS $(objpfx)gencat + $(built-program-cmd) -H $(objpfx)test-gencat.h < $(word 1,$^) > $@; \ + $(evaluate-test) ++ ++$(objpfx)tst-catgets-mem.out: $(objpfx)tst-catgets.out ++ $(common-objpfx)malloc/mtrace $(objpfx)tst-catgets.mtrace > $@; \ ++ $(evaluate-test) + endif +Index: glibc-2.22/catgets/catgets.c +=================================================================== +--- glibc-2.22.orig/catgets/catgets.c ++++ glibc-2.22/catgets/catgets.c +@@ -16,7 +16,6 @@ + License along with the GNU C Library; if not, see + . */ + +-#include + #include + #include + #include +@@ -35,6 +34,7 @@ catopen (const char *cat_name, int flag) + __nl_catd result; + const char *env_var = NULL; + const char *nlspath = NULL; ++ char *tmp = NULL; + + if (strchr (cat_name, '/') == NULL) + { +@@ -54,7 +54,10 @@ catopen (const char *cat_name, int flag) + { + /* Append the system dependent directory. */ + size_t len = strlen (nlspath) + 1 + sizeof NLSPATH; +- char *tmp = alloca (len); ++ tmp = malloc (len); ++ ++ if (__glibc_unlikely (tmp == NULL)) ++ return (nl_catd) -1; + + __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH); + nlspath = tmp; +@@ -65,16 +68,18 @@ catopen (const char *cat_name, int flag) + + result = (__nl_catd) malloc (sizeof (*result)); + if (result == NULL) +- /* We cannot get enough memory. */ +- return (nl_catd) -1; +- +- if (__open_catalog (cat_name, nlspath, env_var, result) != 0) ++ { ++ /* We cannot get enough memory. */ ++ result = (nl_catd) -1; ++ } ++ else if (__open_catalog (cat_name, nlspath, env_var, result) != 0) + { + /* Couldn't open the file. */ + free ((void *) result); +- return (nl_catd) -1; ++ result = (nl_catd) -1; + } + ++ free (tmp); + return (nl_catd) result; + } + +Index: glibc-2.22/catgets/open_catalog.c +=================================================================== +--- glibc-2.22.orig/catgets/open_catalog.c ++++ glibc-2.22/catgets/open_catalog.c +@@ -47,6 +47,7 @@ __open_catalog (const char *cat_name, co + size_t tab_size; + const char *lastp; + int result = -1; ++ char *buf = NULL; + + if (strchr (cat_name, '/') != NULL || nlspath == NULL) + fd = open_not_cancel_2 (cat_name, O_RDONLY); +@@ -57,23 +58,23 @@ __open_catalog (const char *cat_name, co + if (__glibc_unlikely (bufact + (n) >= bufmax)) \ + { \ + char *old_buf = buf; \ +- bufmax += 256 + (n); \ +- buf = (char *) alloca (bufmax); \ +- memcpy (buf, old_buf, bufact); \ ++ bufmax += (bufmax < 256 + (n)) ? 256 + (n) : bufmax; \ ++ buf = realloc (buf, bufmax); \ ++ if (__glibc_unlikely (buf == NULL)) \ ++ { \ ++ free (old_buf); \ ++ return -1; \ ++ } \ + } + + /* The RUN_NLSPATH variable contains a colon separated list of + descriptions where we expect to find catalogs. We have to + recognize certain % substitutions and stop when we found the + first existing file. */ +- char *buf; + size_t bufact; +- size_t bufmax; ++ size_t bufmax = 0; + size_t len; + +- buf = NULL; +- bufmax = 0; +- + fd = -1; + while (*run_nlspath != '\0') + { +@@ -188,7 +189,10 @@ __open_catalog (const char *cat_name, co + + /* Avoid dealing with directories and block devices */ + if (__builtin_expect (fd, 0) < 0) +- return -1; ++ { ++ free (buf); ++ return -1; ++ } + + if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0) < 0) + goto close_unlock_return; +@@ -325,6 +329,7 @@ __open_catalog (const char *cat_name, co + /* Release the lock again. */ + close_unlock_return: + close_not_cancel_no_status (fd); ++ free (buf); + + return result; + } +Index: glibc-2.22/catgets/tst-catgets.c +=================================================================== +--- glibc-2.22.orig/catgets/tst-catgets.c ++++ glibc-2.22/catgets/tst-catgets.c +@@ -1,7 +1,10 @@ ++#include + #include + #include + #include ++#include + #include ++#include + + + static const char *msgs[] = +@@ -12,6 +15,33 @@ static const char *msgs[] = + }; + #define nmsgs (sizeof (msgs) / sizeof (msgs[0])) + ++ ++/* Test for unbounded alloca. */ ++static int ++do_bz17905 (void) ++{ ++ char *buf; ++ struct rlimit rl; ++ nl_catd result; ++ ++ const int sz = 1024 * 1024; ++ ++ getrlimit (RLIMIT_STACK, &rl); ++ rl.rlim_cur = sz; ++ setrlimit (RLIMIT_STACK, &rl); ++ ++ buf = malloc (sz + 1); ++ memset (buf, 'A', sz); ++ buf[sz] = '\0'; ++ setenv ("NLSPATH", buf, 1); ++ ++ result = catopen (buf, NL_CAT_LOCALE); ++ assert (result == (nl_catd) -1); ++ ++ free (buf); ++ return 0; ++} ++ + #define ROUNDS 5 + + static int +@@ -62,6 +92,7 @@ do_test (void) + } + } + ++ result += do_bz17905 (); + return result; + } + diff --git a/errorcheck-mutex-no-elision.patch b/errorcheck-mutex-no-elision.patch new file mode 100644 index 0000000..90ee12a --- /dev/null +++ b/errorcheck-mutex-no-elision.patch @@ -0,0 +1,102 @@ +2016-01-25 Andreas Schwab + + [BZ #17514] + * nptl/pthread_mutex_timedlock.c (pthread_mutex_timedlock) + : Don't do lock elision. + * nptl/Makefile (tests): Add tst-mutex-errorcheck. + * nptl/tst-mutex-errorcheck.c: New file. + +Index: glibc-2.22/nptl/Makefile +=================================================================== +--- glibc-2.22.orig/nptl/Makefile ++++ glibc-2.22/nptl/Makefile +@@ -283,7 +283,8 @@ tests = tst-typesizes \ + tst-getpid3 \ + tst-setuid3 \ + tst-initializers1 $(addprefix tst-initializers1-,c89 gnu89 c99 gnu99) \ +- tst-bad-schedattr ++ tst-bad-schedattr \ ++ tst-thread_local1 tst-mutex-errorcheck + xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \ + tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 + test-srcs = tst-oddstacklimit +Index: glibc-2.22/nptl/pthread_mutex_timedlock.c +=================================================================== +--- glibc-2.22.orig/nptl/pthread_mutex_timedlock.c ++++ glibc-2.22/nptl/pthread_mutex_timedlock.c +@@ -90,7 +90,8 @@ pthread_mutex_timedlock (mutex, abstime) + if (__glibc_unlikely (mutex->__data.__owner == id)) + return EDEADLK; + +- /* FALLTHROUGH */ ++ /* Don't do lock elision on an error checking mutex. */ ++ goto simple; + + case PTHREAD_MUTEX_TIMED_NP: + FORCE_ELISION (mutex, goto elision); +Index: glibc-2.22/nptl/tst-mutex-errorcheck.c +=================================================================== +--- /dev/null ++++ glibc-2.22/nptl/tst-mutex-errorcheck.c +@@ -0,0 +1,61 @@ ++/* Check that error checking mutexes are not subject to lock elision. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ struct timespec tms = { 0 }; ++ pthread_mutex_t mutex; ++ pthread_mutexattr_t mutexattr; ++ int ret = 0; ++ ++ if (pthread_mutexattr_init (&mutexattr) != 0) ++ return 1; ++ if (pthread_mutexattr_settype (&mutexattr, PTHREAD_MUTEX_ERRORCHECK) != 0) ++ return 1; ++ ++ if (pthread_mutex_init (&mutex, &mutexattr) != 0) ++ return 1; ++ if (pthread_mutexattr_destroy (&mutexattr) != 0) ++ return 1; ++ ++ /* The call to pthread_mutex_timedlock erroneously enabled lock elision ++ on the mutex, which then triggered an assertion failure in ++ pthread_mutex_unlock. It would also defeat the error checking nature ++ of the mutex. */ ++ if (pthread_mutex_timedlock (&mutex, &tms) != 0) ++ return 1; ++ if (pthread_mutex_timedlock (&mutex, &tms) != EDEADLK) ++ { ++ printf ("Failed error checking on locked mutex\n"); ++ ret = 1; ++ } ++ ++ if (pthread_mutex_unlock (&mutex) != 0) ++ ret = 1; ++ ++ return ret; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/glibc-testsuite.changes b/glibc-testsuite.changes index 24c79df..50b0b7f 100644 --- a/glibc-testsuite.changes +++ b/glibc-testsuite.changes @@ -1,3 +1,40 @@ +------------------------------------------------------------------- +Thu Feb 18 13:22:19 UTC 2016 - schwab@suse.de + +- isinf-cxx11-conflict.patch: Fix isinf/isnan declaration conflict with + C++11 (bsc#963700, BZ #19439) + +------------------------------------------------------------------- +Wed Feb 17 09:48:26 UTC 2016 - schwab@suse.de + +- tls-dtor-list-mangling.patch: Harden tls_dtor_list with pointer mangling + (BZ #19018) +- prelink-elf-rtype-class.patch: Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits + for prelink (BZ #19178) +- vector-finite-math-aliases.patch: Better workaround for aliases of + *_finite symbols in vector math library (BZ# 19058) +- powerpc-elision-adapt-param.patch: powerpc: Fix usage of elision + transient failure adapt param (BZ #19174) +- catopen-unbound-alloca.patch: Fix unbound alloca in catopen + (CVE-2015-8779, bsc#962739, BZ #17905) +- strftime-range-check.patch: Add range check on time fields + (CVE-2015-8776, bsc#962736, BZ #18985) +- hcreate-overflow-check.patch: Handle overflow in hcreate (CVE-2015-8778, + bsc#962737, BZ #18240) +- errorcheck-mutex-no-elision.patch: Don't do lock elision on an error + checking mutex (bsc#956716, BZ #17514) +- refactor-nan-parsing.patch: Refactor strtod parsing of NaN payloads + (CVE-2014-9761, bsc#962738, BZ #16962) +- send-dg-buffer-overflow.patch: Fix getaddrinfo stack-based buffer + overflow (CVE-2015-7547, bsc#961721, BZ #18665) +- powerpc-lock-elision-race.patch: renamed from + 0001-powerpc-Fix-a-race-condition-when-eliding-a-lock-20150730.patch + +------------------------------------------------------------------- +Mon Feb 15 15:43:02 UTC 2016 - schwab@suse.de + +- Add audit-devel and libcap-devel to BuildRequires, for use by nscd + ------------------------------------------------------------------- Thu Nov 26 14:46:21 UTC 2015 - schwab@suse.de diff --git a/glibc-testsuite.spec b/glibc-testsuite.spec index c3537f8..664d526 100644 --- a/glibc-testsuite.spec +++ b/glibc-testsuite.spec @@ -1,7 +1,7 @@ # # spec file for package glibc-testsuite # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -35,7 +35,9 @@ Summary: Standard Shared Libraries (from the GNU C Library) License: LGPL-2.1+ and SUSE-LGPL-2.1+-with-GCC-exception and GPL-2.0+ Group: System/Libraries # UTILS-SUMMARY-END +BuildRequires: audit-devel BuildRequires: fdupes +BuildRequires: libcap-devel BuildRequires: libselinux-devel BuildRequires: makeinfo BuildRequires: pwdutils @@ -242,6 +244,30 @@ Patch1003: opendir-o-directory-check.patch Patch1004: strcoll-remove-strdiff-opt.patch # PATCH-FIX-UPSTREAM Always enable pointer guard (BZ #18928) Patch1005: ld-pointer-guard.patch +# PATCH-FIX-UPSTREAM Harden tls_dtor_list with pointer mangling (BZ #19018) +Patch1006: tls-dtor-list-mangling.patch +# PATCH-FIX-UPSTREAM PowerPC: Fix a race condition when eliding a lock (BZ #18743) +Patch1007: powerpc-lock-elision-race.patch +# PATCH-FIX-UPSTREAM Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits for prelink (BZ #19178) +Patch1008: prelink-elf-rtype-class.patch +# PATCH-FIX-UPSTREAM Better workaround for aliases of *_finite symbols in vector math library (BZ# 19058) +Patch1009: vector-finite-math-aliases.patch +# PATCH-FIX-UPSTREAM powerpc: Fix usage of elision transient failure adapt param (BZ #19174) +Patch1010: powerpc-elision-adapt-param.patch +# PATCH-FIX-UPSTREAM Fix unbound alloca in catopen (CVE-2015-8779, BZ #17905) +Patch1011: catopen-unbound-alloca.patch +# PATCH-FIX-UPSTREAM Add range check on time fields (CVE-2015-8776, BZ #18985) +Patch1012: strftime-range-check.patch +# PATCH-FIX-UPSTREAM Handle overflow in hcreate (CVE-2015-8778, BZ #18240) +Patch1013: hcreate-overflow-check.patch +# PATCH-FIX-UPSTREAM Don't do lock elision on an error checking mutex (BZ #17514) +Patch1014: errorcheck-mutex-no-elision.patch +# PATCH-FIX-UPSTREAM Refactor strtod parsing of NaN payloads (CVE-2014-9761, BZ #16962) +Patch1015: refactor-nan-parsing.patch +# PATCH-FIX-UPSTREAM Fix getaddrinfo stack-based buffer overflow (CVE-2015-7547, BZ #18665) +Patch1016: send-dg-buffer-overflow.patch +# PATCH-FIX-UPSTREAM Fix isinf/isnan declaration conflict with C++11 (BZ #19439) +Patch1017: isinf-cxx11-conflict.patch ### # Patches awaiting upstream approval @@ -262,16 +288,14 @@ Patch2007: static-dlopen.patch Patch2008: fnmatch-collating-elements.patch # PATCH-FIX-UPSTREAM Properly reread entry after failure in nss_files getent function (BZ #18991) Patch2009: nss-files-long-lines-2.patch -# PATCH-FIX-UPSTREAM PowerPC: Fix a race condition when eliding a lock (BZ #18743) -Patch2010: 0001-powerpc-Fix-a-race-condition-when-eliding-a-lock-20150730.patch # PATCH-FIX-UPSTREAM Fix iconv buffer handling with IGNORE error handler (BZ #18830) -Patch2011: iconv-reset-input-buffer.patch +Patch2010: iconv-reset-input-buffer.patch # PATCH-FIX-UPSTREAM Force rereading TZDEFRULES after it was used to set DST rules only (BZ #19253) -Patch2012: tzset-tzname.patch +Patch2011: tzset-tzname.patch # PATCH-FIX-UPSTREAM Fix resource leak in resolver (BZ #19257) -Patch2013: resolv-mem-leak.patch +Patch2012: resolv-mem-leak.patch # PATCH-FIX-UPSTREAM Reinitialize dl_load_write_lock on fork (BZ #19282) -Patch2014: reinitialize-dl_load_write_lock.patch +Patch2013: reinitialize-dl_load_write_lock.patch # Non-glibc patches # PATCH-FIX-OPENSUSE Remove debianisms from manpages @@ -477,6 +501,18 @@ rm nscd/s-stamp %patch1003 -p1 %patch1004 -p1 %patch1005 -p1 +%patch1006 -p1 +%patch1007 -p1 +%patch1008 -p1 +%patch1009 -p1 +%patch1010 -p1 +%patch1011 -p1 +%patch1012 -p1 +%patch1013 -p1 +%patch1014 -p1 +%patch1015 -p1 +%patch1016 -p1 +%patch1017 -p1 %patch2000 -p1 %patch2002 -p1 @@ -490,7 +526,6 @@ rm nscd/s-stamp %patch2011 -p1 %patch2012 -p1 %patch2013 -p1 -%patch2014 -p1 %patch3000 @@ -1264,6 +1299,9 @@ exit 0 %{_libdir}/libnldbl_nonshared.a %endif %{_libdir}/libmcheck.a +%ifarch x86_64 +%{_libdir}/libmvec_nonshared.a +%endif %{_libdir}/libpthread_nonshared.a %{_libdir}/librpcsvc.a diff --git a/glibc-utils.changes b/glibc-utils.changes index 24c79df..50b0b7f 100644 --- a/glibc-utils.changes +++ b/glibc-utils.changes @@ -1,3 +1,40 @@ +------------------------------------------------------------------- +Thu Feb 18 13:22:19 UTC 2016 - schwab@suse.de + +- isinf-cxx11-conflict.patch: Fix isinf/isnan declaration conflict with + C++11 (bsc#963700, BZ #19439) + +------------------------------------------------------------------- +Wed Feb 17 09:48:26 UTC 2016 - schwab@suse.de + +- tls-dtor-list-mangling.patch: Harden tls_dtor_list with pointer mangling + (BZ #19018) +- prelink-elf-rtype-class.patch: Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits + for prelink (BZ #19178) +- vector-finite-math-aliases.patch: Better workaround for aliases of + *_finite symbols in vector math library (BZ# 19058) +- powerpc-elision-adapt-param.patch: powerpc: Fix usage of elision + transient failure adapt param (BZ #19174) +- catopen-unbound-alloca.patch: Fix unbound alloca in catopen + (CVE-2015-8779, bsc#962739, BZ #17905) +- strftime-range-check.patch: Add range check on time fields + (CVE-2015-8776, bsc#962736, BZ #18985) +- hcreate-overflow-check.patch: Handle overflow in hcreate (CVE-2015-8778, + bsc#962737, BZ #18240) +- errorcheck-mutex-no-elision.patch: Don't do lock elision on an error + checking mutex (bsc#956716, BZ #17514) +- refactor-nan-parsing.patch: Refactor strtod parsing of NaN payloads + (CVE-2014-9761, bsc#962738, BZ #16962) +- send-dg-buffer-overflow.patch: Fix getaddrinfo stack-based buffer + overflow (CVE-2015-7547, bsc#961721, BZ #18665) +- powerpc-lock-elision-race.patch: renamed from + 0001-powerpc-Fix-a-race-condition-when-eliding-a-lock-20150730.patch + +------------------------------------------------------------------- +Mon Feb 15 15:43:02 UTC 2016 - schwab@suse.de + +- Add audit-devel and libcap-devel to BuildRequires, for use by nscd + ------------------------------------------------------------------- Thu Nov 26 14:46:21 UTC 2015 - schwab@suse.de diff --git a/glibc-utils.spec b/glibc-utils.spec index d052987..4010918 100644 --- a/glibc-utils.spec +++ b/glibc-utils.spec @@ -1,7 +1,7 @@ # # spec file for package glibc-utils # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -34,7 +34,9 @@ Summary: Development utilities from GNU C library License: LGPL-2.1+ Group: Development/Languages/C and C++ # UTILS-SUMMARY-END +BuildRequires: audit-devel BuildRequires: fdupes +BuildRequires: libcap-devel BuildRequires: libselinux-devel BuildRequires: makeinfo BuildRequires: pwdutils @@ -241,6 +243,30 @@ Patch1003: opendir-o-directory-check.patch Patch1004: strcoll-remove-strdiff-opt.patch # PATCH-FIX-UPSTREAM Always enable pointer guard (BZ #18928) Patch1005: ld-pointer-guard.patch +# PATCH-FIX-UPSTREAM Harden tls_dtor_list with pointer mangling (BZ #19018) +Patch1006: tls-dtor-list-mangling.patch +# PATCH-FIX-UPSTREAM PowerPC: Fix a race condition when eliding a lock (BZ #18743) +Patch1007: powerpc-lock-elision-race.patch +# PATCH-FIX-UPSTREAM Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits for prelink (BZ #19178) +Patch1008: prelink-elf-rtype-class.patch +# PATCH-FIX-UPSTREAM Better workaround for aliases of *_finite symbols in vector math library (BZ# 19058) +Patch1009: vector-finite-math-aliases.patch +# PATCH-FIX-UPSTREAM powerpc: Fix usage of elision transient failure adapt param (BZ #19174) +Patch1010: powerpc-elision-adapt-param.patch +# PATCH-FIX-UPSTREAM Fix unbound alloca in catopen (CVE-2015-8779, BZ #17905) +Patch1011: catopen-unbound-alloca.patch +# PATCH-FIX-UPSTREAM Add range check on time fields (CVE-2015-8776, BZ #18985) +Patch1012: strftime-range-check.patch +# PATCH-FIX-UPSTREAM Handle overflow in hcreate (CVE-2015-8778, BZ #18240) +Patch1013: hcreate-overflow-check.patch +# PATCH-FIX-UPSTREAM Don't do lock elision on an error checking mutex (BZ #17514) +Patch1014: errorcheck-mutex-no-elision.patch +# PATCH-FIX-UPSTREAM Refactor strtod parsing of NaN payloads (CVE-2014-9761, BZ #16962) +Patch1015: refactor-nan-parsing.patch +# PATCH-FIX-UPSTREAM Fix getaddrinfo stack-based buffer overflow (CVE-2015-7547, BZ #18665) +Patch1016: send-dg-buffer-overflow.patch +# PATCH-FIX-UPSTREAM Fix isinf/isnan declaration conflict with C++11 (BZ #19439) +Patch1017: isinf-cxx11-conflict.patch ### # Patches awaiting upstream approval @@ -261,16 +287,14 @@ Patch2007: static-dlopen.patch Patch2008: fnmatch-collating-elements.patch # PATCH-FIX-UPSTREAM Properly reread entry after failure in nss_files getent function (BZ #18991) Patch2009: nss-files-long-lines-2.patch -# PATCH-FIX-UPSTREAM PowerPC: Fix a race condition when eliding a lock (BZ #18743) -Patch2010: 0001-powerpc-Fix-a-race-condition-when-eliding-a-lock-20150730.patch # PATCH-FIX-UPSTREAM Fix iconv buffer handling with IGNORE error handler (BZ #18830) -Patch2011: iconv-reset-input-buffer.patch +Patch2010: iconv-reset-input-buffer.patch # PATCH-FIX-UPSTREAM Force rereading TZDEFRULES after it was used to set DST rules only (BZ #19253) -Patch2012: tzset-tzname.patch +Patch2011: tzset-tzname.patch # PATCH-FIX-UPSTREAM Fix resource leak in resolver (BZ #19257) -Patch2013: resolv-mem-leak.patch +Patch2012: resolv-mem-leak.patch # PATCH-FIX-UPSTREAM Reinitialize dl_load_write_lock on fork (BZ #19282) -Patch2014: reinitialize-dl_load_write_lock.patch +Patch2013: reinitialize-dl_load_write_lock.patch # Non-glibc patches # PATCH-FIX-OPENSUSE Remove debianisms from manpages @@ -477,6 +501,18 @@ rm nscd/s-stamp %patch1003 -p1 %patch1004 -p1 %patch1005 -p1 +%patch1006 -p1 +%patch1007 -p1 +%patch1008 -p1 +%patch1009 -p1 +%patch1010 -p1 +%patch1011 -p1 +%patch1012 -p1 +%patch1013 -p1 +%patch1014 -p1 +%patch1015 -p1 +%patch1016 -p1 +%patch1017 -p1 %patch2000 -p1 %patch2002 -p1 @@ -490,7 +526,6 @@ rm nscd/s-stamp %patch2011 -p1 %patch2012 -p1 %patch2013 -p1 -%patch2014 -p1 %patch3000 @@ -1264,6 +1299,9 @@ exit 0 %{_libdir}/libnldbl_nonshared.a %endif %{_libdir}/libmcheck.a +%ifarch x86_64 +%{_libdir}/libmvec_nonshared.a +%endif %{_libdir}/libpthread_nonshared.a %{_libdir}/librpcsvc.a diff --git a/glibc.changes b/glibc.changes index 24c79df..50b0b7f 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,40 @@ +------------------------------------------------------------------- +Thu Feb 18 13:22:19 UTC 2016 - schwab@suse.de + +- isinf-cxx11-conflict.patch: Fix isinf/isnan declaration conflict with + C++11 (bsc#963700, BZ #19439) + +------------------------------------------------------------------- +Wed Feb 17 09:48:26 UTC 2016 - schwab@suse.de + +- tls-dtor-list-mangling.patch: Harden tls_dtor_list with pointer mangling + (BZ #19018) +- prelink-elf-rtype-class.patch: Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits + for prelink (BZ #19178) +- vector-finite-math-aliases.patch: Better workaround for aliases of + *_finite symbols in vector math library (BZ# 19058) +- powerpc-elision-adapt-param.patch: powerpc: Fix usage of elision + transient failure adapt param (BZ #19174) +- catopen-unbound-alloca.patch: Fix unbound alloca in catopen + (CVE-2015-8779, bsc#962739, BZ #17905) +- strftime-range-check.patch: Add range check on time fields + (CVE-2015-8776, bsc#962736, BZ #18985) +- hcreate-overflow-check.patch: Handle overflow in hcreate (CVE-2015-8778, + bsc#962737, BZ #18240) +- errorcheck-mutex-no-elision.patch: Don't do lock elision on an error + checking mutex (bsc#956716, BZ #17514) +- refactor-nan-parsing.patch: Refactor strtod parsing of NaN payloads + (CVE-2014-9761, bsc#962738, BZ #16962) +- send-dg-buffer-overflow.patch: Fix getaddrinfo stack-based buffer + overflow (CVE-2015-7547, bsc#961721, BZ #18665) +- powerpc-lock-elision-race.patch: renamed from + 0001-powerpc-Fix-a-race-condition-when-eliding-a-lock-20150730.patch + +------------------------------------------------------------------- +Mon Feb 15 15:43:02 UTC 2016 - schwab@suse.de + +- Add audit-devel and libcap-devel to BuildRequires, for use by nscd + ------------------------------------------------------------------- Thu Nov 26 14:46:21 UTC 2015 - schwab@suse.de diff --git a/glibc.spec b/glibc.spec index b7213da..98433c6 100644 --- a/glibc.spec +++ b/glibc.spec @@ -1,7 +1,7 @@ # # spec file for package glibc # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -35,7 +35,9 @@ Summary: Standard Shared Libraries (from the GNU C Library) License: LGPL-2.1+ and SUSE-LGPL-2.1+-with-GCC-exception and GPL-2.0+ Group: System/Libraries # UTILS-SUMMARY-END +BuildRequires: audit-devel BuildRequires: fdupes +BuildRequires: libcap-devel BuildRequires: libselinux-devel BuildRequires: makeinfo BuildRequires: pwdutils @@ -242,6 +244,30 @@ Patch1003: opendir-o-directory-check.patch Patch1004: strcoll-remove-strdiff-opt.patch # PATCH-FIX-UPSTREAM Always enable pointer guard (BZ #18928) Patch1005: ld-pointer-guard.patch +# PATCH-FIX-UPSTREAM Harden tls_dtor_list with pointer mangling (BZ #19018) +Patch1006: tls-dtor-list-mangling.patch +# PATCH-FIX-UPSTREAM PowerPC: Fix a race condition when eliding a lock (BZ #18743) +Patch1007: powerpc-lock-elision-race.patch +# PATCH-FIX-UPSTREAM Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits for prelink (BZ #19178) +Patch1008: prelink-elf-rtype-class.patch +# PATCH-FIX-UPSTREAM Better workaround for aliases of *_finite symbols in vector math library (BZ# 19058) +Patch1009: vector-finite-math-aliases.patch +# PATCH-FIX-UPSTREAM powerpc: Fix usage of elision transient failure adapt param (BZ #19174) +Patch1010: powerpc-elision-adapt-param.patch +# PATCH-FIX-UPSTREAM Fix unbound alloca in catopen (CVE-2015-8779, BZ #17905) +Patch1011: catopen-unbound-alloca.patch +# PATCH-FIX-UPSTREAM Add range check on time fields (CVE-2015-8776, BZ #18985) +Patch1012: strftime-range-check.patch +# PATCH-FIX-UPSTREAM Handle overflow in hcreate (CVE-2015-8778, BZ #18240) +Patch1013: hcreate-overflow-check.patch +# PATCH-FIX-UPSTREAM Don't do lock elision on an error checking mutex (BZ #17514) +Patch1014: errorcheck-mutex-no-elision.patch +# PATCH-FIX-UPSTREAM Refactor strtod parsing of NaN payloads (CVE-2014-9761, BZ #16962) +Patch1015: refactor-nan-parsing.patch +# PATCH-FIX-UPSTREAM Fix getaddrinfo stack-based buffer overflow (CVE-2015-7547, BZ #18665) +Patch1016: send-dg-buffer-overflow.patch +# PATCH-FIX-UPSTREAM Fix isinf/isnan declaration conflict with C++11 (BZ #19439) +Patch1017: isinf-cxx11-conflict.patch ### # Patches awaiting upstream approval @@ -262,16 +288,14 @@ Patch2007: static-dlopen.patch Patch2008: fnmatch-collating-elements.patch # PATCH-FIX-UPSTREAM Properly reread entry after failure in nss_files getent function (BZ #18991) Patch2009: nss-files-long-lines-2.patch -# PATCH-FIX-UPSTREAM PowerPC: Fix a race condition when eliding a lock (BZ #18743) -Patch2010: 0001-powerpc-Fix-a-race-condition-when-eliding-a-lock-20150730.patch # PATCH-FIX-UPSTREAM Fix iconv buffer handling with IGNORE error handler (BZ #18830) -Patch2011: iconv-reset-input-buffer.patch +Patch2010: iconv-reset-input-buffer.patch # PATCH-FIX-UPSTREAM Force rereading TZDEFRULES after it was used to set DST rules only (BZ #19253) -Patch2012: tzset-tzname.patch +Patch2011: tzset-tzname.patch # PATCH-FIX-UPSTREAM Fix resource leak in resolver (BZ #19257) -Patch2013: resolv-mem-leak.patch +Patch2012: resolv-mem-leak.patch # PATCH-FIX-UPSTREAM Reinitialize dl_load_write_lock on fork (BZ #19282) -Patch2014: reinitialize-dl_load_write_lock.patch +Patch2013: reinitialize-dl_load_write_lock.patch # Non-glibc patches # PATCH-FIX-OPENSUSE Remove debianisms from manpages @@ -477,6 +501,18 @@ rm nscd/s-stamp %patch1003 -p1 %patch1004 -p1 %patch1005 -p1 +%patch1006 -p1 +%patch1007 -p1 +%patch1008 -p1 +%patch1009 -p1 +%patch1010 -p1 +%patch1011 -p1 +%patch1012 -p1 +%patch1013 -p1 +%patch1014 -p1 +%patch1015 -p1 +%patch1016 -p1 +%patch1017 -p1 %patch2000 -p1 %patch2002 -p1 @@ -490,7 +526,6 @@ rm nscd/s-stamp %patch2011 -p1 %patch2012 -p1 %patch2013 -p1 -%patch2014 -p1 %patch3000 @@ -1264,6 +1299,9 @@ exit 0 %{_libdir}/libnldbl_nonshared.a %endif %{_libdir}/libmcheck.a +%ifarch x86_64 +%{_libdir}/libmvec_nonshared.a +%endif %{_libdir}/libpthread_nonshared.a %{_libdir}/librpcsvc.a diff --git a/hcreate-overflow-check.patch b/hcreate-overflow-check.patch new file mode 100644 index 0000000..7890dc6 --- /dev/null +++ b/hcreate-overflow-check.patch @@ -0,0 +1,193 @@ +2016-02-12 Florian Weimer + + * misc/bug18240.c (do_test): Set RLIMIT_AS. + +2016-01-27 Paul Eggert + + [BZ #18240] + * misc/hsearch_r.c (isprime, __hcreate_r): Protect against + unsigned int wraparound. + +2016-01-27 Florian Weimer + + [BZ #18240] + * misc/bug18240.c: New test. + * misc/Makefile (tests): Add it. + +2015-08-25 Ondřej Bílka + + [BZ #18240] + * misc/hsearch_r.c (__hcreate_r): Handle overflow. + +Index: glibc-2.22/misc/Makefile +=================================================================== +--- glibc-2.22.orig/misc/Makefile ++++ glibc-2.22/misc/Makefile +@@ -77,7 +77,7 @@ gpl2lgpl := error.c error.h + + tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ + tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \ +- tst-mntent-blank-corrupt tst-mntent-blank-passno ++ tst-mntent-blank-corrupt tst-mntent-blank-passno bug18240 + ifeq ($(run-built-tests),yes) + tests-special += $(objpfx)tst-error1-mem.out + endif +Index: glibc-2.22/misc/bug18240.c +=================================================================== +--- /dev/null ++++ glibc-2.22/misc/bug18240.c +@@ -0,0 +1,97 @@ ++/* Test integer wraparound in hcreate. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++test_size (size_t size) ++{ ++ int res = hcreate (size); ++ if (res == 0) ++ { ++ if (errno == ENOMEM) ++ return; ++ printf ("error: hcreate (%zu): %m\n", size); ++ exit (1); ++ } ++ char *keys[100]; ++ for (int i = 0; i < 100; ++i) ++ { ++ if (asprintf (keys + i, "%d", i) < 0) ++ { ++ printf ("error: asprintf: %m\n"); ++ exit (1); ++ } ++ ENTRY e = { keys[i], (char *) "value" }; ++ if (hsearch (e, ENTER) == NULL) ++ { ++ printf ("error: hsearch (\"%s\"): %m\n", keys[i]); ++ exit (1); ++ } ++ } ++ hdestroy (); ++ ++ for (int i = 0; i < 100; ++i) ++ free (keys[i]); ++} ++ ++static int ++do_test (void) ++{ ++ /* Limit the size of the process, so that memory allocation will ++ fail without impacting the entire system. */ ++ { ++ struct rlimit limit; ++ if (getrlimit (RLIMIT_AS, &limit) != 0) ++ { ++ printf ("getrlimit (RLIMIT_AS) failed: %m\n"); ++ return 1; ++ } ++ long target = 100 * 1024 * 1024; ++ if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target) ++ { ++ limit.rlim_cur = target; ++ if (setrlimit (RLIMIT_AS, &limit) != 0) ++ { ++ printf ("setrlimit (RLIMIT_AS) failed: %m\n"); ++ return 1; ++ } ++ } ++ } ++ ++ test_size (500); ++ test_size (-1); ++ test_size (-3); ++ test_size (INT_MAX - 2); ++ test_size (INT_MAX - 1); ++ test_size (INT_MAX); ++ test_size (((unsigned) INT_MAX) + 1); ++ test_size (UINT_MAX - 2); ++ test_size (UINT_MAX - 1); ++ test_size (UINT_MAX); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +Index: glibc-2.22/misc/hsearch_r.c +=================================================================== +--- glibc-2.22.orig/misc/hsearch_r.c ++++ glibc-2.22/misc/hsearch_r.c +@@ -19,7 +19,7 @@ + #include + #include + #include +- ++#include + #include + + /* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986 +@@ -46,15 +46,12 @@ static int + isprime (unsigned int number) + { + /* no even number will be passed */ +- unsigned int div = 3; +- +- while (div * div < number && number % div != 0) +- div += 2; +- +- return number % div != 0; ++ for (unsigned int div = 3; div <= number / div; div += 2) ++ if (number % div == 0) ++ return 0; ++ return 1; + } + +- + /* Before using the hash table we must allocate memory for it. + Test for an existing table are done. We allocate one element + more as the found prime number says. This is done for more effective +@@ -81,10 +78,19 @@ __hcreate_r (nel, htab) + use will not work. */ + if (nel < 3) + nel = 3; +- /* Change nel to the first prime number not smaller as nel. */ +- nel |= 1; /* make odd */ +- while (!isprime (nel)) +- nel += 2; ++ ++ /* Change nel to the first prime number in the range [nel, UINT_MAX - 2], ++ The '- 2' means 'nel += 2' cannot overflow. */ ++ for (nel |= 1; ; nel += 2) ++ { ++ if (UINT_MAX - 2 < nel) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ if (isprime (nel)) ++ break; ++ } + + htab->size = nel; + htab->filled = 0; diff --git a/isinf-cxx11-conflict.patch b/isinf-cxx11-conflict.patch new file mode 100644 index 0000000..dec2fd8 --- /dev/null +++ b/isinf-cxx11-conflict.patch @@ -0,0 +1,127 @@ +2016-02-14 Jakub Jelinek + Jonathan Wakely + Carlos O'Donell + + [BZ 19439] + * math/Makefile (tests): Add test-math-isinff. + (CFLAGS-test-math-isinff.cc): Use -std=gnu++11. + * math/bits/mathcalls.h [__USE_MISC]: Use + '|| __MATH_DECLARING_DOUBLE == 0' to relax definition of + functions not in C++11 and which don't conflict e.g. isinff, + isinfl etc. + * math/test-math-isinff.cc: New file. + +2016-01-11 Jonathan Wakely + Adhemerval Zanella + + [BZ #19439] + * math/bits/mathcalls.h + [!__cplusplus || __cplusplus < 201103L] (isinf): Do not declare + prototype. + [!__cplusplus || __cplusplus < 201103L] (isnan): Likewise. + +Index: glibc-2.22/math/Makefile +=================================================================== +--- glibc-2.22.orig/math/Makefile ++++ glibc-2.22/math/Makefile +@@ -108,6 +108,7 @@ tests = test-matherr test-fenv atest-exp + test-tgmath-ret bug-nextafter bug-nexttoward bug-tgmath1 \ + test-tgmath-int test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 test-snan \ + test-fenv-tls test-fenv-preserve test-fenv-return test-fenvinline \ ++ test-math-isinff \ + $(tests-static) + tests-static = test-fpucw-static test-fpucw-ieee-static + # We do the `long double' tests only if this data type is available and +@@ -184,6 +185,8 @@ CPPFLAGS-test-ildoubl.c = -U__LIBC_INTER + $(libm-test-fast-math-cflags) + + ++CFLAGS-test-math-isinff.cc = -std=gnu++11 ++ + # The -lieee module sets the _LIB_VERSION_ switch to IEEE mode + # for error handling in the -lm functions. + install-lib += libieee.a +Index: glibc-2.22/math/bits/mathcalls.h +=================================================================== +--- glibc-2.22.orig/math/bits/mathcalls.h ++++ glibc-2.22/math/bits/mathcalls.h +@@ -196,9 +196,13 @@ __MATHDECL_1 (int,__finite,, (_Mdouble_ + _Mdouble_END_NAMESPACE + + #ifdef __USE_MISC ++# if (!defined __cplusplus \ ++ || __cplusplus < 201103L /* isinf conflicts with C++11. */ \ ++ || __MATH_DECLARING_DOUBLE == 0) /* isinff or isinfl don't. */ + /* Return 0 if VALUE is finite or NaN, +1 if it + is +Infinity, -1 if it is -Infinity. */ + __MATHDECL_1 (int,isinf,, (_Mdouble_ __value)) __attribute__ ((__const__)); ++# endif + + /* Return nonzero if VALUE is finite and not NaN. */ + __MATHDECL_1 (int,finite,, (_Mdouble_ __value)) __attribute__ ((__const__)); +@@ -230,8 +234,12 @@ __END_NAMESPACE_C99 + __MATHDECL_1 (int,__isnan,, (_Mdouble_ __value)) __attribute__ ((__const__)); + + #if defined __USE_MISC || defined __USE_XOPEN ++# if (!defined __cplusplus \ ++ || __cplusplus < 201103L /* isnan conflicts with C++11. */ \ ++ || __MATH_DECLARING_DOUBLE == 0) /* isnanf or isnanl don't. */ + /* Return nonzero if VALUE is not a number. */ + __MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__)); ++# endif + + /* Bessel functions. */ + __MATHCALL (j0,, (_Mdouble_)); +Index: glibc-2.22/math/test-math-isinff.cc +=================================================================== +--- /dev/null ++++ glibc-2.22/math/test-math-isinff.cc +@@ -0,0 +1,48 @@ ++/* Test for bug 19439. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Marek Polacek , 2012. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define _GNU_SOURCE 1 ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ /* Verify that isinff, isinfl, isnanf, and isnanlf are defined ++ in the header under C++11 and can be called. Without the ++ header fix this test will not compile. */ ++ if (isinff (1.0f) ++ || !isinff (INFINITY) ++ || isinfl (1.0L) ++ || !isinfl (INFINITY) ++ || isnanf (2.0f) ++ || !isnanf (NAN) ++ || isnanl (2.0L) ++ || !isnanl (NAN)) ++ { ++ printf ("FAIL: Failed to call is* functions.\n"); ++ exit (1); ++ } ++ printf ("PASS: Able to call isinff, isinfl, isnanf, and isnanl.\n"); ++ exit (0); ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/powerpc-elision-adapt-param.patch b/powerpc-elision-adapt-param.patch new file mode 100644 index 0000000..49d5f23 --- /dev/null +++ b/powerpc-elision-adapt-param.patch @@ -0,0 +1,81 @@ +2015-12-17 Paul E. Murphy + + [BZ #19174] + * sysdeps/powerpc/nptl/elide.h (__elide_lock): Fix usage of + .skip_lock_out_of_tbegin_retries. + * sysdeps/unix/sysv/linux/powerpc/elision-lock.c + (__lll_lock_elision): Likewise, and respect a value of + try_tbegin <= 0. + +Index: glibc-2.22/sysdeps/powerpc/nptl/elide.h +=================================================================== +--- glibc-2.22.orig/sysdeps/powerpc/nptl/elide.h ++++ glibc-2.22/sysdeps/powerpc/nptl/elide.h +@@ -27,7 +27,7 @@ + configurations. Returns true if the system should retry again or false + otherwise. */ + static inline bool +-__get_new_count (uint8_t *adapt_count) ++__get_new_count (uint8_t *adapt_count, int attempt) + { + /* A persistent failure indicates that a retry will probably + result in another failure. Use normal locking now and +@@ -40,7 +40,7 @@ __get_new_count (uint8_t *adapt_count) + } + /* Same logic as above, but for a number of temporary failures in a + a row. */ +- else if (__elision_aconf.skip_lock_out_of_tbegin_retries > 0 ++ else if (attempt <= 1 && __elision_aconf.skip_lock_out_of_tbegin_retries > 0 + && __elision_aconf.try_tbegin > 0) + *adapt_count = __elision_aconf.skip_lock_out_of_tbegin_retries; + return true; +@@ -78,7 +78,7 @@ __get_new_count (uint8_t *adapt_count) + __builtin_tabort (_ABORT_LOCK_BUSY); \ + } \ + else \ +- if (!__get_new_count(&adapt_count)) \ ++ if (!__get_new_count (&adapt_count,i)) \ + break; \ + } \ + ret; \ +Index: glibc-2.22/sysdeps/unix/sysv/linux/powerpc/elision-lock.c +=================================================================== +--- glibc-2.22.orig/sysdeps/unix/sysv/linux/powerpc/elision-lock.c ++++ glibc-2.22/sysdeps/unix/sysv/linux/powerpc/elision-lock.c +@@ -72,8 +72,7 @@ __lll_lock_elision (int *lock, short *ad + goto use_lock; + } + +- int try_begin = aconf.try_tbegin; +- while (1) ++ for (int i = aconf.try_tbegin; i > 0; i--) + { + if (__builtin_tbegin (0)) + { +@@ -87,21 +86,19 @@ __lll_lock_elision (int *lock, short *ad + /* A persistent failure indicates that a retry will probably + result in another failure. Use normal locking now and + for the next couple of calls. */ +- if (try_begin-- <= 0 +- || _TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ())) ++ if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ())) + { + if (aconf.skip_lock_internal_abort > 0) + *adapt_count = aconf.skip_lock_internal_abort; + goto use_lock; + } +- /* Same logic as above, but for for a number of temporary failures +- in a row. */ +- else if (aconf.skip_lock_out_of_tbegin_retries > 0 +- && aconf.try_tbegin > 0) +- *adapt_count = aconf.skip_lock_out_of_tbegin_retries; + } + } + ++ /* Fall back to locks for a bit if retries have been exhausted */ ++ if (aconf.try_tbegin > 0 && aconf.skip_lock_out_of_tbegin_retries > 0) ++ *adapt_count = aconf.skip_lock_out_of_tbegin_retries; ++ + use_lock: + return LLL_LOCK ((*lock), pshared); + } diff --git a/0001-powerpc-Fix-a-race-condition-when-eliding-a-lock-20150730.patch b/powerpc-lock-elision-race.patch similarity index 81% rename from 0001-powerpc-Fix-a-race-condition-when-eliding-a-lock-20150730.patch rename to powerpc-lock-elision-race.patch index 07776c3..06067f6 100644 --- a/0001-powerpc-Fix-a-race-condition-when-eliding-a-lock-20150730.patch +++ b/powerpc-lock-elision-race.patch @@ -1,18 +1,4 @@ -From: Tulio Magno Quites Machado Filho -Date: Thu, 30 Jul 2015 13:48:56 -0300 -Subject: [PATCH][BZ 18743] PowerPC: Fix a race condition when eliding a lock - - [PATCH][BZ 18743] PowerPC: Fix a race condition when eliding a lock - -The previous code used to evaluate the preprocessor token is_lock_free to -a variable before starting a transaction. This behavior can cause an -error if another thread got the lock (without using a transaction) -between the conversion of the token and the beginning of the transaction. - -This patch delays the evaluation of is_lock_free to inside a transaction -by moving this part of the code to the macro ELIDE_LOCK. - -2015-07-30 Tulio Magno Quites Machado Filho +2015-10-20 Tulio Magno Quites Machado Filho [BZ #18743] * sysdeps/powerpc/nptl/elide.h (__elide_lock): Move most of this @@ -24,13 +10,11 @@ by moving this part of the code to the macro ELIDE_LOCK. (__elided_trylock): Moved this code to... (ELIDE_TRYLOCK): ...here. -Signed-off-by: Tulio Magno Quites Machado Filho -Signed-off-by: Michel Normand Index: glibc-2.22/sysdeps/powerpc/nptl/elide.h =================================================================== --- glibc-2.22.orig/sysdeps/powerpc/nptl/elide.h +++ glibc-2.22/sysdeps/powerpc/nptl/elide.h -@@ -23,67 +23,67 @@ +@@ -23,67 +23,78 @@ # include # include @@ -96,7 +80,8 @@ Index: glibc-2.22/sysdeps/powerpc/nptl/elide.h -# define ELIDE_LOCK(adapt_count, is_lock_free) \ - __elide_lock (&(adapt_count), is_lock_free) - -- ++/* CONCURRENCY NOTES: + -static inline bool -__elide_trylock (uint8_t *adapt_count, int is_lock_free, int write) -{ @@ -108,6 +93,16 @@ Index: glibc-2.22/sysdeps/powerpc/nptl/elide.h - } - return false; -} ++ The evaluation of the macro expression is_lock_free encompasses one or ++ more loads from memory locations that are concurrently modified by other ++ threads. For lock elision to work, this evaluation and the rest of the ++ critical section protected by the lock must be atomic because an ++ execution with lock elision must be equivalent to an execution in which ++ the lock would have been actually acquired and released. Therefore, we ++ evaluate is_lock_free inside of the transaction that represents the ++ critical section for which we want to use lock elision, which ensures ++ the atomicity that we require. */ ++ +/* Returns 0 if the lock defined by is_lock_free was elided. + ADAPT_COUNT is a per-lock state variable. */ +# define ELIDE_LOCK(adapt_count, is_lock_free) \ @@ -118,7 +113,6 @@ Index: glibc-2.22/sysdeps/powerpc/nptl/elide.h + else \ + for (int i = __elision_aconf.try_tbegin; i > 0; i--) \ + { \ -+ asm volatile("" ::: "memory"); \ + if (__builtin_tbegin (0)) \ + { \ + if (is_lock_free) \ diff --git a/prelink-elf-rtype-class.patch b/prelink-elf-rtype-class.patch new file mode 100644 index 0000000..2bebff4 --- /dev/null +++ b/prelink-elf-rtype-class.patch @@ -0,0 +1,258 @@ +2015-11-14 H.J. Lu + + * config.make.in (have-glob-dat-reloc): New. + * configure.ac (libc_cv_has_glob_dat): New. Set to yes if + target supports GLOB_DAT relocaton. AC_SUBST. + * configure: Regenerated. + * elf/Makefile (tests): Add tst-prelink. + (tests-special): Add $(objpfx)tst-prelink-cmp.out. + (tst-prelink-ENV): New. + ($(objpfx)tst-prelink-conflict.out): Likewise. + ($(objpfx)tst-prelink-cmp.out): Likewise. + * sysdeps/x86/tst-prelink.c: Moved to ... + * elf/tst-prelink.c: Here. + * sysdeps/x86/tst-prelink.exp: Moved to ... + * elf/tst-prelink.exp: Here. + * sysdeps/x86/Makefile (tests): Don't add tst-prelink. + (tst-prelink-ENV): Removed. + ($(objpfx)tst-prelink-conflict.out): Likewise. + ($(objpfx)tst-prelink-cmp.out): Likewise. + (tests-special): Don't add $(objpfx)tst-prelink-cmp.out. + +2015-11-10 H.J. Lu + + [BZ #19178] + * sysdeps/x86/Makefile (tests): Add tst-prelink. + (tst-prelink-ENV): New. + ($(objpfx)tst-prelink-conflict.out): Likewise. + ($(objpfx)tst-prelink-cmp.out): Likewise. + (tests-special): Add $(objpfx)tst-prelink-cmp.out. + * sysdeps/x86/tst-prelink.c: New file. + * sysdeps/x86/tst-prelink.exp: Likewise. + +2015-11-07 H.J. Lu + + [BZ #19178] + * elf/dl-lookup.c (RTYPE_CLASS_VALID): New. + (RTYPE_CLASS_PLT): Likewise. + (RTYPE_CLASS_COPY): Likewise. + (RTYPE_CLASS_TLS): Likewise. + (_dl_debug_bindings): Use RTYPE_CLASS_TLS and RTYPE_CLASS_VALID + to set relocation type class for DL_DEBUG_PRELINK. Keep only + ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY bits for + DL_DEBUG_PRELINK. + +Index: glibc-2.22/config.make.in +=================================================================== +--- glibc-2.22.orig/config.make.in ++++ glibc-2.22/config.make.in +@@ -51,6 +51,7 @@ have-z-combreloc = @libc_cv_z_combreloc@ + have-z-execstack = @libc_cv_z_execstack@ + have-Bgroup = @libc_cv_Bgroup@ + have-protected-data = @libc_cv_protected_data@ ++have-glob-dat-reloc = @libc_cv_has_glob_dat@ + with-fp = @with_fp@ + old-glibc-headers = @old_glibc_headers@ + unwind-find-fde = @libc_cv_gcc_unwind_find_fde@ +Index: glibc-2.22/configure +=================================================================== +--- glibc-2.22.orig/configure ++++ glibc-2.22/configure +@@ -628,6 +628,7 @@ gnu89_inline + libc_cv_ssp + fno_unit_at_a_time + libc_cv_output_format ++libc_cv_has_glob_dat + libc_cv_hashstyle + libc_cv_fpie + libc_cv_z_execstack +@@ -6335,6 +6336,39 @@ $as_echo "$libc_cv_use_default_link" >&6 + use_default_link=$libc_cv_use_default_link + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_DAT reloc" >&5 ++$as_echo_n "checking for GLOB_DAT reloc... " >&6; } ++if ${libc_cv_has_glob_dat+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ++then ++ if $READELF -rW conftest.so | grep '_GLOB_DAT' > /dev/null; then ++ libc_cv_has_glob_dat=yes ++ else ++ libc_cv_has_glob_dat=no ++ fi ++else ++ libc_cv_has_glob_dat=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_has_glob_dat" >&5 ++$as_echo "$libc_cv_has_glob_dat" >&6; } ++ ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker output format" >&5 + $as_echo_n "checking linker output format... " >&6; } + if ${libc_cv_output_format+:} false; then : +Index: glibc-2.22/configure.ac +=================================================================== +--- glibc-2.22.orig/configure.ac ++++ glibc-2.22/configure.ac +@@ -1535,6 +1535,29 @@ $ac_try" + use_default_link=$libc_cv_use_default_link + fi + ++AC_CACHE_CHECK(for GLOB_DAT reloc, ++ libc_cv_has_glob_dat, [dnl ++cat > conftest.c <&AS_MESSAGE_LOG_FD]) ++then ++dnl look for GLOB_DAT relocation. ++ if $READELF -rW conftest.so | grep '_GLOB_DAT' > /dev/null; then ++ libc_cv_has_glob_dat=yes ++ else ++ libc_cv_has_glob_dat=no ++ fi ++else ++ libc_cv_has_glob_dat=no ++fi ++rm -f conftest*]) ++AC_SUBST(libc_cv_has_glob_dat) ++ + AC_CACHE_CHECK(linker output format, libc_cv_output_format, [dnl + if libc_cv_output_format=` + ${CC-cc} -nostartfiles -nostdlib -Wl,--print-output-format 2>&AS_MESSAGE_LOG_FD` +Index: glibc-2.22/elf/Makefile +=================================================================== +--- glibc-2.22.orig/elf/Makefile ++++ glibc-2.22/elf/Makefile +@@ -292,6 +292,13 @@ check-abi: $(objpfx)check-abi-ld.out + tests-special += $(objpfx)check-abi-ld.out + update-abi: update-abi-ld + ++ifeq ($(have-glob-dat-reloc),yes) ++tests += tst-prelink ++ifeq ($(run-built-tests),yes) ++tests-special += $(objpfx)tst-prelink-cmp.out ++endif ++endif ++ + include ../Rules + + ifeq (yes,$(build-shared)) +@@ -1205,3 +1212,13 @@ $(objpfx)tst-unused-dep.out: $(objpfx)te + $(objpfx)tst-unused-dep-cmp.out: $(objpfx)tst-unused-dep.out + cmp $< /dev/null > $@; \ + $(evaluate-test) ++ ++tst-prelink-ENV = LD_TRACE_PRELINKING=1 ++ ++$(objpfx)tst-prelink-conflict.out: $(objpfx)tst-prelink.out ++ grep stdout $< | grep conflict | $(AWK) '{ print $$10, $$11 }' > $@ ++ ++$(objpfx)tst-prelink-cmp.out: tst-prelink.exp \ ++ $(objpfx)tst-prelink-conflict.out ++ cmp $^ > $@; \ ++ $(evaluate-test) +Index: glibc-2.22/elf/dl-lookup.c +=================================================================== +--- glibc-2.22.orig/elf/dl-lookup.c ++++ glibc-2.22/elf/dl-lookup.c +@@ -1016,6 +1016,18 @@ _dl_debug_bindings (const char *undef_na + #ifdef SHARED + if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) + { ++/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with ++ LD_TRACE_PRELINKING. */ ++#define RTYPE_CLASS_VALID 8 ++#define RTYPE_CLASS_PLT (8|1) ++#define RTYPE_CLASS_COPY (8|2) ++#define RTYPE_CLASS_TLS (8|4) ++#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1 ++# error ELF_RTYPE_CLASS_PLT must be 0 or 1! ++#endif ++#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2 ++# error ELF_RTYPE_CLASS_COPY must be 0 or 2! ++#endif + int conflict = 0; + struct sym_val val = { NULL, NULL }; + +@@ -1071,12 +1083,17 @@ _dl_debug_bindings (const char *undef_na + + if (value->s) + { ++ /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY ++ bits since since prelink only uses them. */ ++ type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY; + if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) + == STT_TLS)) +- type_class = 4; ++ /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS. */ ++ type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID; + else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) + == STT_GNU_IFUNC)) +- type_class |= 8; ++ /* Set the RTYPE_CLASS_VALID bit. */ ++ type_class |= RTYPE_CLASS_VALID; + } + + if (conflict +Index: glibc-2.22/elf/tst-prelink.c +=================================================================== +--- /dev/null ++++ glibc-2.22/elf/tst-prelink.c +@@ -0,0 +1,30 @@ ++/* Test the output from the environment variable, LD_TRACE_PRELINKING, ++ for prelink. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++static int ++do_test (void) ++{ ++ fprintf (stdout, "hello\n"); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +Index: glibc-2.22/elf/tst-prelink.exp +=================================================================== +--- /dev/null ++++ glibc-2.22/elf/tst-prelink.exp +@@ -0,0 +1 @@ ++/0 stdout diff --git a/refactor-nan-parsing.patch b/refactor-nan-parsing.patch new file mode 100644 index 0000000..1d51201 --- /dev/null +++ b/refactor-nan-parsing.patch @@ -0,0 +1,896 @@ +2015-11-24 Joseph Myers + + * stdlib/strtod_nan.c: New file. + * stdlib/strtod_nan_double.h: Likewise. + * stdlib/strtod_nan_float.h: Likewise. + * stdlib/strtod_nan_main.c: Likewise. + * stdlib/strtod_nan_narrow.h: Likewise. + * stdlib/strtod_nan_wide.h: Likewise. + * stdlib/strtof_nan.c: Likewise. + * stdlib/strtold_nan.c: Likewise. + * sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h: Likewise. + * sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h: Likewise. + * sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h: Likewise. + * wcsmbs/wcstod_nan.c: Likewise. + * wcsmbs/wcstof_nan.c: Likewise. + * wcsmbs/wcstold_nan.c: Likewise. + * stdlib/Makefile (routines): Add strtof_nan, strtod_nan and + strtold_nan. + * wcsmbs/Makefile (routines): Add wcstod_nan, wcstold_nan and + wcstof_nan. + * include/stdlib.h (__strtof_nan): Declare and use + libc_hidden_proto. + (__strtod_nan): Likewise. + (__strtold_nan): Likewise. + (__wcstof_nan): Likewise. + (__wcstod_nan): Likewise. + (__wcstold_nan): Likewise. + * include/wchar.h (____wcstoull_l_internal): Declare. + * stdlib/strtod_l.c: Do not include . + (____strtoull_l_internal): Remove declaration. + (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + (STRTOULL): Likewise. + (____STRTOF_INTERNAL): Use STRTOF_NAN to parse NaN payload. + * stdlib/strtof_l.c (____strtoull_l_internal): Remove declaration. + (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-128/strtold_l.c (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-128ibm/strtold_l.c (STRTOF_NAN): Define + macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-64-128/strtold_l.c (STRTOF_NAN): Define + macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-96/strtold_l.c (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + * wcsmbs/wcstod_l.c (____wcstoull_l_internal): Remove declaration. + * wcsmbs/wcstof_l.c (____wcstoull_l_internal): Likewise. + * wcsmbs/wcstold_l.c (____wcstoull_l_internal): Likewise. + +Index: glibc-2.22/include/stdlib.h +=================================================================== +--- glibc-2.22.orig/include/stdlib.h ++++ glibc-2.22/include/stdlib.h +@@ -203,6 +203,24 @@ libc_hidden_proto (strtoll) + libc_hidden_proto (strtoul) + libc_hidden_proto (strtoull) + ++extern float __strtof_nan (const char *, char **, char) internal_function; ++extern double __strtod_nan (const char *, char **, char) internal_function; ++extern long double __strtold_nan (const char *, char **, char) ++ internal_function; ++extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t) ++ internal_function; ++extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t) ++ internal_function; ++extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t) ++ internal_function; ++ ++libc_hidden_proto (__strtof_nan) ++libc_hidden_proto (__strtod_nan) ++libc_hidden_proto (__strtold_nan) ++libc_hidden_proto (__wcstof_nan) ++libc_hidden_proto (__wcstod_nan) ++libc_hidden_proto (__wcstold_nan) ++ + extern char *__ecvt (double __value, int __ndigit, int *__restrict __decpt, + int *__restrict __sign); + extern char *__fcvt (double __value, int __ndigit, int *__restrict __decpt, +Index: glibc-2.22/include/wchar.h +=================================================================== +--- glibc-2.22.orig/include/wchar.h ++++ glibc-2.22/include/wchar.h +@@ -52,6 +52,9 @@ extern unsigned long long int __wcstoull + __restrict __endptr, + int __base, + int __group) __THROW; ++extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, ++ wchar_t **, int, int, ++ __locale_t); + libc_hidden_proto (__wcstof_internal) + libc_hidden_proto (__wcstod_internal) + libc_hidden_proto (__wcstold_internal) +Index: glibc-2.22/stdlib/Makefile +=================================================================== +--- glibc-2.22.orig/stdlib/Makefile ++++ glibc-2.22/stdlib/Makefile +@@ -50,6 +50,7 @@ routines := \ + strtol_l strtoul_l strtoll_l strtoull_l \ + strtof strtod strtold \ + strtof_l strtod_l strtold_l \ ++ strtof_nan strtod_nan strtold_nan \ + system canonicalize \ + a64l l64a \ + rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg \ +Index: glibc-2.22/stdlib/strtod_l.c +=================================================================== +--- glibc-2.22.orig/stdlib/strtod_l.c ++++ glibc-2.22/stdlib/strtod_l.c +@@ -20,8 +20,6 @@ + #include + + extern double ____strtod_l_internal (const char *, char **, int, __locale_t); +-extern unsigned long long int ____strtoull_l_internal (const char *, char **, +- int, int, __locale_t); + + /* Configuration part. These macros are defined by `strtold.c', + `strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the +@@ -33,27 +31,20 @@ extern unsigned long long int ____strtou + # ifdef USE_WIDE_CHAR + # define STRTOF wcstod_l + # define __STRTOF __wcstod_l ++# define STRTOF_NAN __wcstod_nan + # else + # define STRTOF strtod_l + # define __STRTOF __strtod_l ++# define STRTOF_NAN __strtod_nan + # endif + # define MPN2FLOAT __mpn_construct_double + # define FLOAT_HUGE_VAL HUGE_VAL +-# define SET_MANTISSA(flt, mant) \ +- do { union ieee754_double u; \ +- u.d = (flt); \ +- u.ieee_nan.mantissa0 = (mant) >> 32; \ +- u.ieee_nan.mantissa1 = (mant); \ +- if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ +- (flt) = u.d; \ +- } while (0) + #endif + /* End of configuration part. */ + + #include + #include + #include +-#include + #include "../locale/localeinfo.h" + #include + #include +@@ -104,7 +95,6 @@ extern unsigned long long int ____strtou + # define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr) + # define STRNCASECMP(S1, S2, N) \ + __wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr) +-# define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc) + #else + # define STRING_TYPE char + # define CHAR_TYPE char +@@ -116,7 +106,6 @@ extern unsigned long long int ____strtou + # define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr) + # define STRNCASECMP(S1, S2, N) \ + __strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr) +-# define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc) + #endif + + +@@ -655,33 +644,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group + if (*cp == L_('(')) + { + const STRING_TYPE *startp = cp; +- do +- ++cp; +- while ((*cp >= L_('0') && *cp <= L_('9')) +- || ({ CHAR_TYPE lo = TOLOWER (*cp); +- lo >= L_('a') && lo <= L_('z'); }) +- || *cp == L_('_')); +- +- if (*cp != L_(')')) +- /* The closing brace is missing. Only match the NAN +- part. */ +- cp = startp; ++ STRING_TYPE *endp; ++ retval = STRTOF_NAN (cp + 1, &endp, L_(')')); ++ if (*endp == L_(')')) ++ /* Consume the closing parenthesis. */ ++ cp = endp + 1; + else +- { +- /* This is a system-dependent way to specify the +- bitmask used for the NaN. We expect it to be +- a number which is put in the mantissa of the +- number. */ +- STRING_TYPE *endp; +- unsigned long long int mant; +- +- mant = STRTOULL (startp + 1, &endp, 0); +- if (endp == cp) +- SET_MANTISSA (retval, mant); +- +- /* Consume the closing brace. */ +- ++cp; +- } ++ /* Only match the NAN part. */ ++ cp = startp; + } + + if (endptr != NULL) +Index: glibc-2.22/stdlib/strtod_nan.c +=================================================================== +--- /dev/null ++++ glibc-2.22/stdlib/strtod_nan.c +@@ -0,0 +1,24 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow ++ strings, double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define STRTOD_NAN __strtod_nan ++#include +Index: glibc-2.22/stdlib/strtod_nan_double.h +=================================================================== +--- /dev/null ++++ glibc-2.22/stdlib/strtod_nan_double.h +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. For double. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee754_double u; \ ++ u.d = (flt); \ ++ u.ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.ieee_nan.mantissa1 = (mant); \ ++ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ ++ (flt) = u.d; \ ++ } \ ++ while (0) +Index: glibc-2.22/stdlib/strtod_nan_float.h +=================================================================== +--- /dev/null ++++ glibc-2.22/stdlib/strtod_nan_float.h +@@ -0,0 +1,29 @@ ++/* Convert string for NaN payload to corresponding NaN. For float. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT float ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee754_float u; \ ++ u.f = (flt); \ ++ u.ieee_nan.mantissa = (mant); \ ++ if (u.ieee.mantissa != 0) \ ++ (flt) = u.f; \ ++ } \ ++ while (0) +Index: glibc-2.22/stdlib/strtod_nan_main.c +=================================================================== +--- /dev/null ++++ glibc-2.22/stdlib/strtod_nan_main.c +@@ -0,0 +1,63 @@ ++/* Convert string for NaN payload to corresponding NaN. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* If STR starts with an optional n-char-sequence as defined by ISO C ++ (a sequence of ASCII letters, digits and underscores), followed by ++ ENDC, return a NaN whose payload is set based on STR. Otherwise, ++ return a default NAN. If ENDPTR is not NULL, set *ENDPTR to point ++ to the character after the initial n-char-sequence. */ ++ ++internal_function ++FLOAT ++STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc) ++{ ++ const STRING_TYPE *cp = str; ++ ++ while ((*cp >= L_('0') && *cp <= L_('9')) ++ || (*cp >= L_('A') && *cp <= L_('Z')) ++ || (*cp >= L_('a') && *cp <= L_('z')) ++ || *cp == L_('_')) ++ ++cp; ++ ++ FLOAT retval = NAN; ++ if (*cp != endc) ++ goto out; ++ ++ /* This is a system-dependent way to specify the bitmask used for ++ the NaN. We expect it to be a number which is put in the ++ mantissa of the number. */ ++ STRING_TYPE *endp; ++ unsigned long long int mant; ++ ++ mant = STRTOULL (str, &endp, 0); ++ if (endp == cp) ++ SET_MANTISSA (retval, mant); ++ ++ out: ++ if (endptr != NULL) ++ *endptr = (STRING_TYPE *) cp; ++ return retval; ++} ++libc_hidden_def (STRTOD_NAN) +Index: glibc-2.22/stdlib/strtod_nan_narrow.h +=================================================================== +--- /dev/null ++++ glibc-2.22/stdlib/strtod_nan_narrow.h +@@ -0,0 +1,22 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow strings. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRING_TYPE char ++#define L_(Ch) Ch ++#define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, \ ++ _nl_C_locobj_ptr) +Index: glibc-2.22/stdlib/strtod_nan_wide.h +=================================================================== +--- /dev/null ++++ glibc-2.22/stdlib/strtod_nan_wide.h +@@ -0,0 +1,22 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRING_TYPE wchar_t ++#define L_(Ch) L##Ch ++#define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, \ ++ _nl_C_locobj_ptr) +Index: glibc-2.22/stdlib/strtof_l.c +=================================================================== +--- glibc-2.22.orig/stdlib/strtof_l.c ++++ glibc-2.22/stdlib/strtof_l.c +@@ -20,26 +20,19 @@ + #include + + extern float ____strtof_l_internal (const char *, char **, int, __locale_t); +-extern unsigned long long int ____strtoull_l_internal (const char *, char **, +- int, int, __locale_t); + + #define FLOAT float + #define FLT FLT + #ifdef USE_WIDE_CHAR + # define STRTOF wcstof_l + # define __STRTOF __wcstof_l ++# define STRTOF_NAN __wcstof_nan + #else + # define STRTOF strtof_l + # define __STRTOF __strtof_l ++# define STRTOF_NAN __strtof_nan + #endif + #define MPN2FLOAT __mpn_construct_float + #define FLOAT_HUGE_VAL HUGE_VALF +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee754_float u; \ +- u.f = (flt); \ +- u.ieee_nan.mantissa = (mant); \ +- if (u.ieee.mantissa != 0) \ +- (flt) = u.f; \ +- } while (0) + + #include "strtod_l.c" +Index: glibc-2.22/stdlib/strtof_nan.c +=================================================================== +--- /dev/null ++++ glibc-2.22/stdlib/strtof_nan.c +@@ -0,0 +1,24 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow ++ strings, float. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define STRTOD_NAN __strtof_nan ++#include +Index: glibc-2.22/stdlib/strtold_nan.c +=================================================================== +--- /dev/null ++++ glibc-2.22/stdlib/strtold_nan.c +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow ++ strings, long double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* This function is unused if long double and double have the same ++ representation. */ ++#ifndef __NO_LONG_DOUBLE_MATH ++# include ++# include ++ ++# define STRTOD_NAN __strtold_nan ++# include ++#endif +Index: glibc-2.22/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h +=================================================================== +--- /dev/null ++++ glibc-2.22/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h +@@ -0,0 +1,33 @@ ++/* Convert string for NaN payload to corresponding NaN. For ldbl-128. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT long double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee854_long_double u; \ ++ u.d = (flt); \ ++ u.ieee_nan.mantissa0 = 0; \ ++ u.ieee_nan.mantissa1 = 0; \ ++ u.ieee_nan.mantissa2 = (mant) >> 32; \ ++ u.ieee_nan.mantissa3 = (mant); \ ++ if ((u.ieee.mantissa0 | u.ieee.mantissa1 \ ++ | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \ ++ (flt) = u.d; \ ++ } \ ++ while (0) +Index: glibc-2.22/sysdeps/ieee754/ldbl-128/strtold_l.c +=================================================================== +--- glibc-2.22.orig/sysdeps/ieee754/ldbl-128/strtold_l.c ++++ glibc-2.22/sysdeps/ieee754/ldbl-128/strtold_l.c +@@ -25,22 +25,13 @@ + #ifdef USE_WIDE_CHAR + # define STRTOF wcstold_l + # define __STRTOF __wcstold_l ++# define STRTOF_NAN __wcstold_nan + #else + # define STRTOF strtold_l + # define __STRTOF __strtold_l ++# define STRTOF_NAN __strtold_nan + #endif + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee854_long_double u; \ +- u.d = (flt); \ +- u.ieee_nan.mantissa0 = 0; \ +- u.ieee_nan.mantissa1 = 0; \ +- u.ieee_nan.mantissa2 = (mant) >> 32; \ +- u.ieee_nan.mantissa3 = (mant); \ +- if ((u.ieee.mantissa0 | u.ieee.mantissa1 \ +- | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \ +- (flt) = u.d; \ +- } while (0) + + #include +Index: glibc-2.22/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h +=================================================================== +--- /dev/null ++++ glibc-2.22/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. For ldbl-128ibm. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT long double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ibm_extended_long_double u; \ ++ u.ld = (flt); \ ++ u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.d[0].ieee_nan.mantissa1 = (mant); \ ++ if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \ ++ (flt) = u.ld; \ ++ } \ ++ while (0) +Index: glibc-2.22/sysdeps/ieee754/ldbl-128ibm/strtold_l.c +=================================================================== +--- glibc-2.22.orig/sysdeps/ieee754/ldbl-128ibm/strtold_l.c ++++ glibc-2.22/sysdeps/ieee754/ldbl-128ibm/strtold_l.c +@@ -30,25 +30,19 @@ extern long double ____new_wcstold_l (co + # define STRTOF __new_wcstold_l + # define __STRTOF ____new_wcstold_l + # define ____STRTOF_INTERNAL ____wcstold_l_internal ++# define STRTOF_NAN __wcstold_nan + #else + extern long double ____new_strtold_l (const char *, char **, __locale_t); + # define STRTOF __new_strtold_l + # define __STRTOF ____new_strtold_l + # define ____STRTOF_INTERNAL ____strtold_l_internal ++# define STRTOF_NAN __strtold_nan + #endif + extern __typeof (__STRTOF) STRTOF; + libc_hidden_proto (__STRTOF) + libc_hidden_proto (STRTOF) + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-# define SET_MANTISSA(flt, mant) \ +- do { union ibm_extended_long_double u; \ +- u.ld = (flt); \ +- u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \ +- u.d[0].ieee_nan.mantissa1 = (mant); \ +- if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \ +- (flt) = u.ld; \ +- } while (0) + + #include + +Index: glibc-2.22/sysdeps/ieee754/ldbl-64-128/strtold_l.c +=================================================================== +--- glibc-2.22.orig/sysdeps/ieee754/ldbl-64-128/strtold_l.c ++++ glibc-2.22/sysdeps/ieee754/ldbl-64-128/strtold_l.c +@@ -30,28 +30,19 @@ extern long double ____new_wcstold_l (co + # define STRTOF __new_wcstold_l + # define __STRTOF ____new_wcstold_l + # define ____STRTOF_INTERNAL ____wcstold_l_internal ++# define STRTOF_NAN __wcstold_nan + #else + extern long double ____new_strtold_l (const char *, char **, __locale_t); + # define STRTOF __new_strtold_l + # define __STRTOF ____new_strtold_l + # define ____STRTOF_INTERNAL ____strtold_l_internal ++# define STRTOF_NAN __strtold_nan + #endif + extern __typeof (__STRTOF) STRTOF; + libc_hidden_proto (__STRTOF) + libc_hidden_proto (STRTOF) + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee854_long_double u; \ +- u.d = (flt); \ +- u.ieee_nan.mantissa0 = 0; \ +- u.ieee_nan.mantissa1 = 0; \ +- u.ieee_nan.mantissa2 = (mant) >> 32; \ +- u.ieee_nan.mantissa3 = (mant); \ +- if ((u.ieee.mantissa0 | u.ieee.mantissa1 \ +- | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \ +- (flt) = u.d; \ +- } while (0) + + #include + +Index: glibc-2.22/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h +=================================================================== +--- /dev/null ++++ glibc-2.22/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. For ldbl-96. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT long double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee854_long_double u; \ ++ u.d = (flt); \ ++ u.ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.ieee_nan.mantissa1 = (mant); \ ++ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ ++ (flt) = u.d; \ ++ } \ ++ while (0) +Index: glibc-2.22/sysdeps/ieee754/ldbl-96/strtold_l.c +=================================================================== +--- glibc-2.22.orig/sysdeps/ieee754/ldbl-96/strtold_l.c ++++ glibc-2.22/sysdeps/ieee754/ldbl-96/strtold_l.c +@@ -25,19 +25,13 @@ + #ifdef USE_WIDE_CHAR + # define STRTOF wcstold_l + # define __STRTOF __wcstold_l ++# define STRTOF_NAN __wcstold_nan + #else + # define STRTOF strtold_l + # define __STRTOF __strtold_l ++# define STRTOF_NAN __strtold_nan + #endif + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee854_long_double u; \ +- u.d = (flt); \ +- u.ieee_nan.mantissa0 = (mant) >> 32; \ +- u.ieee_nan.mantissa1 = (mant); \ +- if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ +- (flt) = u.d; \ +- } while (0) + + #include +Index: glibc-2.22/wcsmbs/Makefile +=================================================================== +--- glibc-2.22.orig/wcsmbs/Makefile ++++ glibc-2.22/wcsmbs/Makefile +@@ -33,6 +33,7 @@ routines := wcscat wcschr wcscmp wcscpy + wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \ + wcstol_l wcstoul_l wcstoll_l wcstoull_l \ + wcstod_l wcstold_l wcstof_l \ ++ wcstod_nan wcstold_nan wcstof_nan \ + wcscoll wcsxfrm \ + wcwidth wcswidth \ + wcscoll_l wcsxfrm_l \ +Index: glibc-2.22/wcsmbs/wcstod_l.c +=================================================================== +--- glibc-2.22.orig/wcsmbs/wcstod_l.c ++++ glibc-2.22/wcsmbs/wcstod_l.c +@@ -23,9 +23,6 @@ + + extern double ____wcstod_l_internal (const wchar_t *, wchar_t **, int, + __locale_t); +-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, +- wchar_t **, int, int, +- __locale_t); + + #define USE_WIDE_CHAR 1 + +Index: glibc-2.22/wcsmbs/wcstod_nan.c +=================================================================== +--- /dev/null ++++ glibc-2.22/wcsmbs/wcstod_nan.c +@@ -0,0 +1,23 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings, double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "../stdlib/strtod_nan_wide.h" ++#include "../stdlib/strtod_nan_double.h" ++ ++#define STRTOD_NAN __wcstod_nan ++#include "../stdlib/strtod_nan_main.c" +Index: glibc-2.22/wcsmbs/wcstof_l.c +=================================================================== +--- glibc-2.22.orig/wcsmbs/wcstof_l.c ++++ glibc-2.22/wcsmbs/wcstof_l.c +@@ -25,8 +25,5 @@ + + extern float ____wcstof_l_internal (const wchar_t *, wchar_t **, int, + __locale_t); +-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, +- wchar_t **, int, int, +- __locale_t); + + #include +Index: glibc-2.22/wcsmbs/wcstof_nan.c +=================================================================== +--- /dev/null ++++ glibc-2.22/wcsmbs/wcstof_nan.c +@@ -0,0 +1,23 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings, float. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "../stdlib/strtod_nan_wide.h" ++#include "../stdlib/strtod_nan_float.h" ++ ++#define STRTOD_NAN __wcstof_nan ++#include "../stdlib/strtod_nan_main.c" +Index: glibc-2.22/wcsmbs/wcstold_l.c +=================================================================== +--- glibc-2.22.orig/wcsmbs/wcstold_l.c ++++ glibc-2.22/wcsmbs/wcstold_l.c +@@ -24,8 +24,5 @@ + + extern long double ____wcstold_l_internal (const wchar_t *, wchar_t **, int, + __locale_t); +-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, +- wchar_t **, int, int, +- __locale_t); + + #include +Index: glibc-2.22/wcsmbs/wcstold_nan.c +=================================================================== +--- /dev/null ++++ glibc-2.22/wcsmbs/wcstold_nan.c +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings, ++ long double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* This function is unused if long double and double have the same ++ representation. */ ++#ifndef __NO_LONG_DOUBLE_MATH ++# include "../stdlib/strtod_nan_wide.h" ++# include ++ ++# define STRTOD_NAN __wcstold_nan ++# include "../stdlib/strtod_nan_main.c" ++#endif diff --git a/send-dg-buffer-overflow.patch b/send-dg-buffer-overflow.patch new file mode 100644 index 0000000..ae71f49 --- /dev/null +++ b/send-dg-buffer-overflow.patch @@ -0,0 +1,569 @@ +2016-02-15 Carlos O'Donell + + [BZ #18665] + * resolv/nss_dns/dns-host.c (gaih_getanswer_slice): Always set + *herrno_p. + (gaih_getanswer): Document functional behviour. Return tryagain + if any result is tryagain. + * resolv/res_query.c (__libc_res_nsearch): Set buffer size to zero + when freed. + * resolv/res_send.c: Add copyright text. + (__libc_res_nsend): Document that MAXPACKET is expected. + (send_vc): Document. Remove buffer reuse. + (send_dg): Document. Remove buffer reuse. Set *thisanssizp to set the + size of the buffer. Add Dprint for truncated UDP buffer. + +Index: glibc-2.22/resolv/nss_dns/dns-host.c +=================================================================== +--- glibc-2.22.orig/resolv/nss_dns/dns-host.c ++++ glibc-2.22/resolv/nss_dns/dns-host.c +@@ -1031,7 +1031,10 @@ gaih_getanswer_slice (const querybuf *an + int h_namelen = 0; + + if (ancount == 0) +- return NSS_STATUS_NOTFOUND; ++ { ++ *h_errnop = HOST_NOT_FOUND; ++ return NSS_STATUS_NOTFOUND; ++ } + + while (ancount-- > 0 && cp < end_of_message && had_error == 0) + { +@@ -1208,7 +1211,14 @@ gaih_getanswer_slice (const querybuf *an + /* Special case here: if the resolver sent a result but it only + contains a CNAME while we are looking for a T_A or T_AAAA record, + we fail with NOTFOUND instead of TRYAGAIN. */ +- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND; ++ if (canon != NULL) ++ { ++ *h_errnop = HOST_NOT_FOUND; ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ *h_errnop = NETDB_INTERNAL; ++ return NSS_STATUS_TRYAGAIN; + } + + +@@ -1222,11 +1232,101 @@ gaih_getanswer (const querybuf *answer1, + + enum nss_status status = NSS_STATUS_NOTFOUND; + ++ /* Combining the NSS status of two distinct queries requires some ++ compromise and attention to symmetry (A or AAAA queries can be ++ returned in any order). What follows is a breakdown of how this ++ code is expected to work and why. We discuss only SUCCESS, ++ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns ++ that apply (though RETURN and MERGE exist). We make a distinction ++ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable). ++ A recoverable TRYAGAIN is almost always due to buffer size issues ++ and returns ERANGE in errno and the caller is expected to retry ++ with a larger buffer. ++ ++ Lastly, you may be tempted to make significant changes to the ++ conditions in this code to bring about symmetry between responses. ++ Please don't change anything without due consideration for ++ expected application behaviour. Some of the synthesized responses ++ aren't very well thought out and sometimes appear to imply that ++ IPv4 responses are always answer 1, and IPv6 responses are always ++ answer 2, but that's not true (see the implementation of send_dg ++ and send_vc to see response can arrive in any order, particularly ++ for UDP). However, we expect it holds roughly enough of the time ++ that this code works, but certainly needs to be fixed to make this ++ a more robust implementation. ++ ++ ---------------------------------------------- ++ | Answer 1 Status / | Synthesized | Reason | ++ | Answer 2 Status | Status | | ++ |--------------------------------------------| ++ | SUCCESS/SUCCESS | SUCCESS | [1] | ++ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] | ++ | SUCCESS/TRYAGAIN' | SUCCESS | [1] | ++ | SUCCESS/NOTFOUND | SUCCESS | [1] | ++ | SUCCESS/UNAVAIL | SUCCESS | [1] | ++ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] | ++ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] | ++ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] | ++ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] | ++ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] | ++ | TRYAGAIN'/SUCCESS | SUCCESS | [3] | ++ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] | ++ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] | ++ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] | ++ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] | ++ | NOTFOUND/SUCCESS | SUCCESS | [3] | ++ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] | ++ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] | ++ | NOTFOUND/NOTFOUND | NOTFOUND | [3] | ++ | NOTFOUND/UNAVAIL | UNAVAIL | [3] | ++ | UNAVAIL/SUCCESS | UNAVAIL | [4] | ++ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] | ++ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] | ++ | UNAVAIL/NOTFOUND | UNAVAIL | [4] | ++ | UNAVAIL/UNAVAIL | UNAVAIL | [4] | ++ ---------------------------------------------- ++ ++ [1] If the first response is a success we return success. ++ This ignores the state of the second answer and in fact ++ incorrectly sets errno and h_errno to that of the second ++ answer. However because the response is a success we ignore ++ *errnop and *h_errnop (though that means you touched errno on ++ success). We are being conservative here and returning the ++ likely IPv4 response in the first answer as a success. ++ ++ [2] If the first response is a recoverable TRYAGAIN we return ++ that instead of looking at the second response. The ++ expectation here is that we have failed to get an IPv4 response ++ and should retry both queries. ++ ++ [3] If the first response was not a SUCCESS and the second ++ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN, ++ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the ++ result from the second response, otherwise the first responses ++ status is used. Again we have some odd side-effects when the ++ second response is NOTFOUND because we overwrite *errnop and ++ *h_errnop that means that a first answer of NOTFOUND might see ++ its *errnop and *h_errnop values altered. Whether it matters ++ in practice that a first response NOTFOUND has the wrong ++ *errnop and *h_errnop is undecided. ++ ++ [4] If the first response is UNAVAIL we return that instead of ++ looking at the second response. The expectation here is that ++ it will have failed similarly e.g. configuration failure. ++ ++ [5] Testing this code is complicated by the fact that truncated ++ second response buffers might be returned as SUCCESS if the ++ first answer is a SUCCESS. To fix this we add symmetry to ++ TRYAGAIN with the second response. If the second response ++ is a recoverable error we now return TRYAGIN even if the first ++ response was SUCCESS. */ ++ + if (anslen1 > 0) + status = gaih_getanswer_slice(answer1, anslen1, qname, + &pat, &buffer, &buflen, + errnop, h_errnop, ttlp, + &first); ++ + if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND + || (status == NSS_STATUS_TRYAGAIN + /* We want to look at the second answer in case of an +@@ -1242,8 +1342,15 @@ gaih_getanswer (const querybuf *answer1, + &pat, &buffer, &buflen, + errnop, h_errnop, ttlp, + &first); ++ /* Use the second response status in some cases. */ + if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND) + status = status2; ++ /* Do not return a truncated second response (unless it was ++ unavoidable e.g. unrecoverable TRYAGAIN). */ ++ if (status == NSS_STATUS_SUCCESS ++ && (status2 == NSS_STATUS_TRYAGAIN ++ && *errnop == ERANGE && *h_errnop != NO_RECOVERY)) ++ status = NSS_STATUS_TRYAGAIN; + } + + return status; +Index: glibc-2.22/resolv/res_query.c +=================================================================== +--- glibc-2.22.orig/resolv/res_query.c ++++ glibc-2.22/resolv/res_query.c +@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp, + { + free (*answerp2); + *answerp2 = NULL; ++ *nanswerp2 = 0; + *answerp2_malloced = 0; + } + } +@@ -447,6 +448,7 @@ __libc_res_nsearch(res_state statp, + { + free (*answerp2); + *answerp2 = NULL; ++ *nanswerp2 = 0; + *answerp2_malloced = 0; + } + +@@ -521,6 +523,7 @@ __libc_res_nsearch(res_state statp, + { + free (*answerp2); + *answerp2 = NULL; ++ *nanswerp2 = 0; + *answerp2_malloced = 0; + } + if (saved_herrno != -1) +Index: glibc-2.22/resolv/res_send.c +=================================================================== +--- glibc-2.22.orig/resolv/res_send.c ++++ glibc-2.22/resolv/res_send.c +@@ -1,3 +1,20 @@ ++/* Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1985, 1989, 1993 + * The Regents of the University of California. All rights reserved. +@@ -363,6 +380,8 @@ __libc_res_nsend(res_state statp, const + #ifdef USE_HOOKS + if (__glibc_unlikely (statp->qhook || statp->rhook)) { + if (anssiz < MAXPACKET && ansp) { ++ /* Always allocate MAXPACKET, callers expect ++ this specific size. */ + u_char *buf = malloc (MAXPACKET); + if (buf == NULL) + return (-1); +@@ -638,6 +657,77 @@ get_nsaddr (res_state statp, int n) + return (struct sockaddr *) (void *) &statp->nsaddr_list[n]; + } + ++/* The send_vc function is responsible for sending a DNS query over TCP ++ to the nameserver numbered NS from the res_state STATP i.e. ++ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and ++ IPv6 queries at the same serially on the same socket. ++ ++ Please note that for TCP there is no way to disable sending both ++ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP ++ and sends the queries serially and waits for the result after each ++ sent query. This implemetnation should be corrected to honour these ++ options. ++ ++ Please also note that for TCP we send both queries over the same ++ socket one after another. This technically violates best practice ++ since the server is allowed to read the first query, respond, and ++ then close the socket (to service another client). If the server ++ does this, then the remaining second query in the socket data buffer ++ will cause the server to send the client an RST which will arrive ++ asynchronously and the client's OS will likely tear down the socket ++ receive buffer resulting in a potentially short read and lost ++ response data. This will force the client to retry the query again, ++ and this process may repeat until all servers and connection resets ++ are exhausted and then the query will fail. It's not known if this ++ happens with any frequency in real DNS server implementations. This ++ implementation should be corrected to use two sockets by default for ++ parallel queries. ++ ++ The query stored in BUF of BUFLEN length is sent first followed by ++ the query stored in BUF2 of BUFLEN2 length. Queries are sent ++ serially on the same socket. ++ ++ Answers to the query are stored firstly in *ANSP up to a max of ++ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP ++ is non-NULL (to indicate that modifying the answer buffer is allowed) ++ then malloc is used to allocate a new response buffer and ANSCP and ++ ANSP will both point to the new buffer. If more than *ANSSIZP bytes ++ are needed but ANSCP is NULL, then as much of the response as ++ possible is read into the buffer, but the results will be truncated. ++ When truncation happens because of a small answer buffer the DNS ++ packets header field TC will bet set to 1, indicating a truncated ++ message and the rest of the socket data will be read and discarded. ++ ++ Answers to the query are stored secondly in *ANSP2 up to a max of ++ *ANSSIZP2 bytes, with the actual response length stored in ++ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2 ++ is non-NULL (required for a second query) then malloc is used to ++ allocate a new response buffer, *ANSSIZP2 is set to the new buffer ++ size and *ANSP2_MALLOCED is set to 1. ++ ++ The ANSP2_MALLOCED argument will eventually be removed as the ++ change in buffer pointer can be used to detect the buffer has ++ changed and that the caller should use free on the new buffer. ++ ++ Note that the answers may arrive in any order from the server and ++ therefore the first and second answer buffers may not correspond to ++ the first and second queries. ++ ++ It is not supported to call this function with a non-NULL ANSP2 ++ but a NULL ANSCP. Put another way, you can call send_vc with a ++ single unmodifiable buffer or two modifiable buffers, but no other ++ combination is supported. ++ ++ It is the caller's responsibility to free the malloc allocated ++ buffers by detecting that the pointers have changed from their ++ original values i.e. *ANSCP or *ANSP2 has changed. ++ ++ If errors are encountered then *TERRNO is set to an appropriate ++ errno value and a zero result is returned for a recoverable error, ++ and a less-than zero result is returned for a non-recoverable error. ++ ++ If no errors are encountered then *TERRNO is left unmodified and ++ a the length of the first response in bytes is returned. */ + static int + send_vc(res_state statp, + const u_char *buf, int buflen, const u_char *buf2, int buflen2, +@@ -647,11 +737,7 @@ send_vc(res_state statp, + { + const HEADER *hp = (HEADER *) buf; + const HEADER *hp2 = (HEADER *) buf2; +- u_char *ans = *ansp; +- int orig_anssizp = *anssizp; +- // XXX REMOVE +- // int anssiz = *anssizp; +- HEADER *anhp = (HEADER *) ans; ++ HEADER *anhp = (HEADER *) *ansp; + struct sockaddr *nsap = get_nsaddr (statp, ns); + int truncating, connreset, n; + /* On some architectures compiler might emit a warning indicating +@@ -743,6 +829,8 @@ send_vc(res_state statp, + * Receive length & response + */ + int recvresp1 = 0; ++ /* Skip the second response if there is no second query. ++ To do that we mark the second response as received. */ + int recvresp2 = buf2 == NULL; + uint16_t rlen16; + read_len: +@@ -779,40 +867,14 @@ send_vc(res_state statp, + u_char **thisansp; + int *thisresplenp; + if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) { ++ /* We have not received any responses ++ yet or we only have one response to ++ receive. */ + thisanssizp = anssizp; + thisansp = anscp ?: ansp; + assert (anscp != NULL || ansp2 == NULL); + thisresplenp = &resplen; + } else { +- if (*anssizp != MAXPACKET) { +- /* No buffer allocated for the first +- reply. We can try to use the rest +- of the user-provided buffer. */ +-#if __GNUC_PREREQ (4, 7) +- DIAG_PUSH_NEEDS_COMMENT; +- DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); +-#endif +-#if _STRING_ARCH_unaligned +- *anssizp2 = orig_anssizp - resplen; +- *ansp2 = *ansp + resplen; +-#else +- int aligned_resplen +- = ((resplen + __alignof__ (HEADER) - 1) +- & ~(__alignof__ (HEADER) - 1)); +- *anssizp2 = orig_anssizp - aligned_resplen; +- *ansp2 = *ansp + aligned_resplen; +-#endif +-#if __GNUC_PREREQ (4, 7) +- DIAG_POP_NEEDS_COMMENT; +-#endif +- } else { +- /* The first reply did not fit into the +- user-provided buffer. Maybe the second +- answer will. */ +- *anssizp2 = orig_anssizp; +- *ansp2 = *ansp; +- } +- + thisanssizp = anssizp2; + thisansp = ansp2; + thisresplenp = resplen2; +@@ -820,10 +882,14 @@ send_vc(res_state statp, + anhp = (HEADER *) *thisansp; + + *thisresplenp = rlen; +- if (rlen > *thisanssizp) { +- /* Yes, we test ANSCP here. If we have two buffers +- both will be allocatable. */ +- if (__glibc_likely (anscp != NULL)) { ++ /* Is the answer buffer too small? */ ++ if (*thisanssizp < rlen) { ++ /* If the current buffer is not the the static ++ user-supplied buffer then we can reallocate ++ it. */ ++ if (thisansp != NULL && thisansp != ansp) { ++ /* Always allocate MAXPACKET, callers expect ++ this specific size. */ + u_char *newp = malloc (MAXPACKET); + if (newp == NULL) { + *terrno = ENOMEM; +@@ -835,6 +901,9 @@ send_vc(res_state statp, + if (thisansp == ansp2) + *ansp2_malloced = 1; + anhp = (HEADER *) newp; ++ /* A uint16_t can't be larger than MAXPACKET ++ thus it's safe to allocate MAXPACKET but ++ read RLEN bytes instead. */ + len = rlen; + } else { + Dprint(statp->options & RES_DEBUG, +@@ -997,6 +1066,66 @@ reopen (res_state statp, int *terrno, in + return 1; + } + ++/* The send_dg function is responsible for sending a DNS query over UDP ++ to the nameserver numbered NS from the res_state STATP i.e. ++ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries ++ along with the ability to send the query in parallel for both stacks ++ (default) or serially (RES_SINGLKUP). It also supports serial lookup ++ with a close and reopen of the socket used to talk to the server ++ (RES_SNGLKUPREOP) to work around broken name servers. ++ ++ The query stored in BUF of BUFLEN length is sent first followed by ++ the query stored in BUF2 of BUFLEN2 length. Queries are sent ++ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP). ++ ++ Answers to the query are stored firstly in *ANSP up to a max of ++ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP ++ is non-NULL (to indicate that modifying the answer buffer is allowed) ++ then malloc is used to allocate a new response buffer and ANSCP and ++ ANSP will both point to the new buffer. If more than *ANSSIZP bytes ++ are needed but ANSCP is NULL, then as much of the response as ++ possible is read into the buffer, but the results will be truncated. ++ When truncation happens because of a small answer buffer the DNS ++ packets header field TC will bet set to 1, indicating a truncated ++ message, while the rest of the UDP packet is discarded. ++ ++ Answers to the query are stored secondly in *ANSP2 up to a max of ++ *ANSSIZP2 bytes, with the actual response length stored in ++ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2 ++ is non-NULL (required for a second query) then malloc is used to ++ allocate a new response buffer, *ANSSIZP2 is set to the new buffer ++ size and *ANSP2_MALLOCED is set to 1. ++ ++ The ANSP2_MALLOCED argument will eventually be removed as the ++ change in buffer pointer can be used to detect the buffer has ++ changed and that the caller should use free on the new buffer. ++ ++ Note that the answers may arrive in any order from the server and ++ therefore the first and second answer buffers may not correspond to ++ the first and second queries. ++ ++ It is not supported to call this function with a non-NULL ANSP2 ++ but a NULL ANSCP. Put another way, you can call send_vc with a ++ single unmodifiable buffer or two modifiable buffers, but no other ++ combination is supported. ++ ++ It is the caller's responsibility to free the malloc allocated ++ buffers by detecting that the pointers have changed from their ++ original values i.e. *ANSCP or *ANSP2 has changed. ++ ++ If an answer is truncated because of UDP datagram DNS limits then ++ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to ++ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1 ++ if any progress was made reading a response from the nameserver and ++ is used by the caller to distinguish between ECONNREFUSED and ++ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1). ++ ++ If errors are encountered then *TERRNO is set to an appropriate ++ errno value and a zero result is returned for a recoverable error, ++ and a less-than zero result is returned for a non-recoverable error. ++ ++ If no errors are encountered then *TERRNO is left unmodified and ++ a the length of the first response in bytes is returned. */ + static int + send_dg(res_state statp, + const u_char *buf, int buflen, const u_char *buf2, int buflen2, +@@ -1006,8 +1135,6 @@ send_dg(res_state statp, + { + const HEADER *hp = (HEADER *) buf; + const HEADER *hp2 = (HEADER *) buf2; +- u_char *ans = *ansp; +- int orig_anssizp = *anssizp; + struct timespec now, timeout, finish; + struct pollfd pfd[1]; + int ptimeout; +@@ -1040,6 +1167,8 @@ send_dg(res_state statp, + int need_recompute = 0; + int nwritten = 0; + int recvresp1 = 0; ++ /* Skip the second response if there is no second query. ++ To do that we mark the second response as received. */ + int recvresp2 = buf2 == NULL; + pfd[0].fd = EXT(statp).nssocks[ns]; + pfd[0].events = POLLOUT; +@@ -1203,55 +1332,56 @@ send_dg(res_state statp, + int *thisresplenp; + + if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) { ++ /* We have not received any responses ++ yet or we only have one response to ++ receive. */ + thisanssizp = anssizp; + thisansp = anscp ?: ansp; + assert (anscp != NULL || ansp2 == NULL); + thisresplenp = &resplen; + } else { +- if (*anssizp != MAXPACKET) { +- /* No buffer allocated for the first +- reply. We can try to use the rest +- of the user-provided buffer. */ +-#if _STRING_ARCH_unaligned +- *anssizp2 = orig_anssizp - resplen; +- *ansp2 = *ansp + resplen; +-#else +- int aligned_resplen +- = ((resplen + __alignof__ (HEADER) - 1) +- & ~(__alignof__ (HEADER) - 1)); +- *anssizp2 = orig_anssizp - aligned_resplen; +- *ansp2 = *ansp + aligned_resplen; +-#endif +- } else { +- /* The first reply did not fit into the +- user-provided buffer. Maybe the second +- answer will. */ +- *anssizp2 = orig_anssizp; +- *ansp2 = *ansp; +- } +- + thisanssizp = anssizp2; + thisansp = ansp2; + thisresplenp = resplen2; + } + + if (*thisanssizp < MAXPACKET +- /* Yes, we test ANSCP here. If we have two buffers +- both will be allocatable. */ +- && anscp ++ /* If the current buffer is not the the static ++ user-supplied buffer then we can reallocate ++ it. */ ++ && (thisansp != NULL && thisansp != ansp) + #ifdef FIONREAD ++ /* Is the size too small? */ + && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0 + || *thisanssizp < *thisresplenp) + #endif + ) { ++ /* Always allocate MAXPACKET, callers expect ++ this specific size. */ + u_char *newp = malloc (MAXPACKET); + if (newp != NULL) { +- *anssizp = MAXPACKET; +- *thisansp = ans = newp; ++ *thisanssizp = MAXPACKET; ++ *thisansp = newp; + if (thisansp == ansp2) + *ansp2_malloced = 1; + } + } ++ /* We could end up with truncation if anscp was NULL ++ (not allowed to change caller's buffer) and the ++ response buffer size is too small. This isn't a ++ reliable way to detect truncation because the ioctl ++ may be an inaccurate report of the UDP message size. ++ Therefore we use this only to issue debug output. ++ To do truncation accurately with UDP we need ++ MSG_TRUNC which is only available on Linux. We ++ can abstract out the Linux-specific feature in the ++ future to detect truncation. */ ++ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) { ++ Dprint(statp->options & RES_DEBUG, ++ (stdout, ";; response may be truncated (UDP)\n") ++ ); ++ } ++ + HEADER *anhp = (HEADER *) *thisansp; + socklen_t fromlen = sizeof(struct sockaddr_in6); + assert (sizeof(from) <= fromlen); diff --git a/strftime-range-check.patch b/strftime-range-check.patch new file mode 100644 index 0000000..27ff3d2 --- /dev/null +++ b/strftime-range-check.patch @@ -0,0 +1,126 @@ +2015-09-26 Paul Pluzhnikov + + [BZ #18985] + * time/strftime_l.c (a_wkday, f_wkday, a_month, f_month): Range check. + (__strftime_internal): Likewise. + * time/tst-strftime.c (do_bz18985): New test. + (do_test): Call it. + +Index: glibc-2.22/time/strftime_l.c +=================================================================== +--- glibc-2.22.orig/time/strftime_l.c ++++ glibc-2.22/time/strftime_l.c +@@ -510,13 +510,17 @@ __strftime_internal (s, maxsize, format, + only a few elements. Dereference the pointers only if the format + requires this. Then it is ok to fail if the pointers are invalid. */ + # define a_wkday \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)) ++ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))) + # define f_wkday \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)) ++ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))) + # define a_month \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)) ++ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))) + # define f_month \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)) ++ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))) + # define ampm \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ + ? NLW(PM_STR) : NLW(AM_STR))) +@@ -526,8 +530,10 @@ __strftime_internal (s, maxsize, format, + # define ap_len STRLEN (ampm) + #else + # if !HAVE_STRFTIME +-# define f_wkday (weekday_name[tp->tm_wday]) +-# define f_month (month_name[tp->tm_mon]) ++# define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6 \ ++ ? "?" : weekday_name[tp->tm_wday]) ++# define f_month (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : month_name[tp->tm_mon]) + # define a_wkday f_wkday + # define a_month f_month + # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11)) +@@ -1321,7 +1327,7 @@ __strftime_internal (s, maxsize, format, + *tzset_called = true; + } + # endif +- zone = tzname[tp->tm_isdst]; ++ zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?"; + } + #endif + if (! zone) +Index: glibc-2.22/time/tst-strftime.c +=================================================================== +--- glibc-2.22.orig/time/tst-strftime.c ++++ glibc-2.22/time/tst-strftime.c +@@ -4,6 +4,56 @@ + #include + + ++static int ++do_bz18985 (void) ++{ ++ char buf[1000]; ++ struct tm ttm; ++ int rc, ret = 0; ++ ++ memset (&ttm, 1, sizeof (ttm)); ++ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ ++ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); ++ ++ if (rc == 66) ++ { ++ const char expected[] ++ = "? ? ? ? ? ? 16843009 16843009:16843009:16843009 16844909 +467836 ?"; ++ if (0 != strcmp (buf, expected)) ++ { ++ printf ("expected:\n %s\ngot:\n %s\n", expected, buf); ++ ret += 1; ++ } ++ } ++ else ++ { ++ printf ("expected 66, got %d\n", rc); ++ ret += 1; ++ } ++ ++ /* Check negative values as well. */ ++ memset (&ttm, 0xFF, sizeof (ttm)); ++ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ ++ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); ++ ++ if (rc == 30) ++ { ++ const char expected[] = "? ? ? ? ? ? -1 -1:-1:-1 1899 "; ++ if (0 != strcmp (buf, expected)) ++ { ++ printf ("expected:\n %s\ngot:\n %s\n", expected, buf); ++ ret += 1; ++ } ++ } ++ else ++ { ++ printf ("expected 30, got %d\n", rc); ++ ret += 1; ++ } ++ ++ return ret; ++} ++ + static struct + { + const char *fmt; +@@ -104,7 +154,7 @@ do_test (void) + } + } + +- return result; ++ return result + do_bz18985 (); + } + + #define TEST_FUNCTION do_test () diff --git a/tls-dtor-list-mangling.patch b/tls-dtor-list-mangling.patch new file mode 100644 index 0000000..302eaa2 --- /dev/null +++ b/tls-dtor-list-mangling.patch @@ -0,0 +1,37 @@ +2015-10-06 Florian Weimer + + [BZ #19018] + * stdlib/cxa_thread_atexit_impl.c (__cxa_thread_atexit_impl): + Mangle function pointer before storing it. + (__call_tls_dtors): Demangle function pointer before calling it. + +Index: glibc-2.22/stdlib/cxa_thread_atexit_impl.c +=================================================================== +--- glibc-2.22.orig/stdlib/cxa_thread_atexit_impl.c ++++ glibc-2.22/stdlib/cxa_thread_atexit_impl.c +@@ -98,6 +98,10 @@ static __thread struct link_map *lm_cach + int + __cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol) + { ++#ifdef PTR_MANGLE ++ PTR_MANGLE (func); ++#endif ++ + /* Prepend. */ + struct dtor_list *new = calloc (1, sizeof (struct dtor_list)); + new->func = func; +@@ -142,9 +146,13 @@ __call_tls_dtors (void) + while (tls_dtor_list) + { + struct dtor_list *cur = tls_dtor_list; ++ dtor_func func = cur->func; ++#ifdef PTR_DEMANGLE ++ PTR_DEMANGLE (func); ++#endif + + tls_dtor_list = tls_dtor_list->next; +- cur->func (cur->obj); ++ func (cur->obj); + + /* Ensure that the MAP dereference happens before + l_tls_dtor_count decrement. That way, we protect this access from a diff --git a/vector-finite-math-aliases.patch b/vector-finite-math-aliases.patch new file mode 100644 index 0000000..602a884 --- /dev/null +++ b/vector-finite-math-aliases.patch @@ -0,0 +1,149 @@ +2015-12-03 Andrew Senkevich + + * math/Makefile ($(inst_libdir)/libm.so): Corrected path to + libmvec_nonshared.a + +2015-11-27 Andrew Senkevich + + [BZ #19058] + * math/Makefile ($(inst_libdir)/libm.so): Added libmvec_nonshared.a to + AS_NEEDED. + * sysdeps/x86/fpu/bits/math-vector.h: Removed code with asm aliases + workaround. + * sysdeps/x86_64/fpu/Makefile (libmvec-support, + libmvec-static-only-routines): Added new file. + * sysdeps/x86_64/fpu/svml_finite_alias.S: New file. + * NEWS: Mention this fix. + +Index: glibc-2.22/math/Makefile +=================================================================== +--- glibc-2.22.orig/math/Makefile ++++ glibc-2.22/math/Makefile +@@ -98,7 +98,7 @@ $(inst_libdir)/libm.so: $(common-objpfx) + (echo '/* GNU ld script'; echo '*/';\ + cat $<; \ + echo 'GROUP ( $(slibdir)/libm.so$(libm.so-version) ' \ +- 'AS_NEEDED ( $(slibdir)/libmvec.so$(libmvec.so-version) ) )' \ ++ 'AS_NEEDED ( $(libdir)/libmvec_nonshared.a $(slibdir)/libmvec.so$(libmvec.so-version) ) )' \ + ) > $@ + endif + +Index: glibc-2.22/sysdeps/x86/fpu/bits/math-vector.h +=================================================================== +--- glibc-2.22.orig/sysdeps/x86/fpu/bits/math-vector.h ++++ glibc-2.22/sysdeps/x86/fpu/bits/math-vector.h +@@ -53,34 +53,5 @@ + # undef __DECL_SIMD_powf + # define __DECL_SIMD_powf __DECL_SIMD_x86_64 + +-/* Workaround to exclude unnecessary symbol aliases in libmvec +- while GCC creates the vector names based on scalar asm name. +- Corresponding discussion started at +- . */ +-__asm__ ("_ZGVbN2v___log_finite = _ZGVbN2v_log"); +-__asm__ ("_ZGVcN4v___log_finite = _ZGVcN4v_log"); +-__asm__ ("_ZGVdN4v___log_finite = _ZGVdN4v_log"); +-__asm__ ("_ZGVeN8v___log_finite = _ZGVeN8v_log"); +-__asm__ ("_ZGVbN4v___logf_finite = _ZGVbN4v_logf"); +-__asm__ ("_ZGVcN8v___logf_finite = _ZGVcN8v_logf"); +-__asm__ ("_ZGVdN8v___logf_finite = _ZGVdN8v_logf"); +-__asm__ ("_ZGVeN16v___logf_finite = _ZGVeN16v_logf"); +-__asm__ ("_ZGVbN2v___exp_finite = _ZGVbN2v_exp"); +-__asm__ ("_ZGVcN4v___exp_finite = _ZGVcN4v_exp"); +-__asm__ ("_ZGVdN4v___exp_finite = _ZGVdN4v_exp"); +-__asm__ ("_ZGVeN8v___exp_finite = _ZGVeN8v_exp"); +-__asm__ ("_ZGVbN4v___expf_finite = _ZGVbN4v_expf"); +-__asm__ ("_ZGVcN8v___expf_finite = _ZGVcN8v_expf"); +-__asm__ ("_ZGVdN8v___expf_finite = _ZGVdN8v_expf"); +-__asm__ ("_ZGVeN16v___expf_finite = _ZGVeN16v_expf"); +-__asm__ ("_ZGVbN2vv___pow_finite = _ZGVbN2vv_pow"); +-__asm__ ("_ZGVcN4vv___pow_finite = _ZGVcN4vv_pow"); +-__asm__ ("_ZGVdN4vv___pow_finite = _ZGVdN4vv_pow"); +-__asm__ ("_ZGVeN8vv___pow_finite = _ZGVeN8vv_pow"); +-__asm__ ("_ZGVbN4vv___powf_finite = _ZGVbN4vv_powf"); +-__asm__ ("_ZGVcN8vv___powf_finite = _ZGVcN8vv_powf"); +-__asm__ ("_ZGVdN8vv___powf_finite = _ZGVdN8vv_powf"); +-__asm__ ("_ZGVeN16vv___powf_finite = _ZGVeN16vv_powf"); +- + # endif + #endif +Index: glibc-2.22/sysdeps/x86_64/fpu/Makefile +=================================================================== +--- glibc-2.22.orig/sysdeps/x86_64/fpu/Makefile ++++ glibc-2.22/sysdeps/x86_64/fpu/Makefile +@@ -20,7 +20,10 @@ libmvec-support += svml_d_cos2_core svml + svml_d_pow_data svml_s_powf4_core svml_s_powf8_core_avx \ + svml_s_powf8_core svml_s_powf16_core svml_s_powf_data \ + svml_s_sincosf4_core svml_s_sincosf8_core_avx \ +- svml_s_sincosf8_core svml_s_sincosf16_core init-arch ++ svml_s_sincosf8_core svml_s_sincosf16_core init-arch \ ++ svml_finite_alias ++ ++libmvec-static-only-routines = svml_finite_alias + endif + + # Variables for libmvec tests. +Index: glibc-2.22/sysdeps/x86_64/fpu/svml_finite_alias.S +=================================================================== +--- /dev/null ++++ glibc-2.22/sysdeps/x86_64/fpu/svml_finite_alias.S +@@ -0,0 +1,59 @@ ++/* These aliases added as workaround to exclude unnecessary symbol ++ aliases in libmvec.so while compiler creates the vector names ++ based on scalar asm name. Corresponding discussion is at ++ . ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define ALIAS_IMPL(alias, target) \ ++ENTRY (alias); \ ++ call target; \ ++ ret; \ ++END (alias) ++ ++ .text ++ALIAS_IMPL (_ZGVbN2v___log_finite, _ZGVbN2v_log) ++ALIAS_IMPL (_ZGVcN4v___log_finite, _ZGVcN4v_log) ++ALIAS_IMPL (_ZGVdN4v___log_finite, _ZGVdN4v_log) ++ALIAS_IMPL (_ZGVeN8v___log_finite, _ZGVeN8v_log) ++ ++ALIAS_IMPL (_ZGVbN4v___logf_finite, _ZGVbN4v_logf) ++ALIAS_IMPL (_ZGVcN8v___logf_finite, _ZGVcN8v_logf) ++ALIAS_IMPL (_ZGVdN8v___logf_finite, _ZGVdN8v_logf) ++ALIAS_IMPL (_ZGVeN16v___logf_finite, _ZGVeN16v_logf) ++ ++ALIAS_IMPL (_ZGVbN2v___exp_finite, _ZGVbN2v_exp) ++ALIAS_IMPL (_ZGVcN4v___exp_finite, _ZGVcN4v_exp) ++ALIAS_IMPL (_ZGVdN4v___exp_finite, _ZGVdN4v_exp) ++ALIAS_IMPL (_ZGVeN8v___exp_finite, _ZGVeN8v_exp) ++ ++ALIAS_IMPL (_ZGVbN4v___expf_finite, _ZGVbN4v_expf) ++ALIAS_IMPL (_ZGVcN8v___expf_finite, _ZGVcN8v_expf) ++ALIAS_IMPL (_ZGVdN8v___expf_finite, _ZGVdN8v_expf) ++ALIAS_IMPL (_ZGVeN16v___expf_finite, _ZGVeN16v_expf) ++ ++ALIAS_IMPL (_ZGVbN2vv___pow_finite, _ZGVbN2vv_pow) ++ALIAS_IMPL (_ZGVcN4vv___pow_finite, _ZGVcN4vv_pow) ++ALIAS_IMPL (_ZGVdN4vv___pow_finite, _ZGVdN4vv_pow) ++ALIAS_IMPL (_ZGVeN8vv___pow_finite, _ZGVeN8vv_pow) ++ ++ALIAS_IMPL (_ZGVbN4vv___powf_finite, _ZGVbN4vv_powf) ++ALIAS_IMPL (_ZGVcN8vv___powf_finite, _ZGVcN8vv_powf) ++ALIAS_IMPL (_ZGVdN8vv___powf_finite, _ZGVdN8vv_powf) ++ALIAS_IMPL (_ZGVeN16vv___powf_finite, _ZGVeN16vv_powf)