[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#808559: jessie-pu: package glibc/2.19-18+deb8u2



Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian.org@packages.debian.org
Usertags: pu

Dear stable release team,

We would like to update the glibc package in Jessie to fix the known
security issues, fix an issue with nscd affecting debian-edu and a
workaround for possible data corruption on Broadwell CPUs when not
using BIOS or microcode updates.

This is done partly by updating to the latest commit of the stable
branch and using a few additional patches. The diff can be found at the
bottom of this mail. It might looks big, but this is mostly due to the
new tests matching the issues fixed in the upstream stable branch and
the renaming of the Intel blacklisting patch to extend it to Broadwell
CPUs. All the corresponding changes are already in testing and unstable.

Thanks,
Aurelien


Index: debian/patches/git-updates.diff
===================================================================
--- debian/patches/git-updates.diff	(révision 6511)
+++ debian/patches/git-updates.diff	(copie de travail)
@@ -1,10 +1,75 @@
 GIT update of git://sourceware.org/git/glibc.git/release/2.19/master from glibc-2.19
 
 diff --git a/ChangeLog b/ChangeLog
-index 81c393a..0eb6c3f 100644
+index 81c393a..e82ba7d 100644
 --- a/ChangeLog
 +++ b/ChangeLog
-@@ -1,3 +1,341 @@
+@@ -1,3 +1,406 @@
++2015-12-20  Siddhesh Poyarekar  <siddhesh@redhat.com>
++
++	[BZ #16758]
++	* nscd/netgroupcache.c (addinnetgrX): Succeed if triplet has
++	blank values.
++
++	[BZ #16759]
++	* inet/getnetgrent_r.c (get_nonempty_val): New function.
++	(nscd_getnetgrent): Use it.
++
++	[BZ #16760]
++	* nscd/netgroupcache.c (addgetnetgrentX): Use memmove instead
++	of stpcpy.
++
++2015-11-24  Andreas Schwab  <schwab@suse.de>
++
++	[BZ #17062]
++	* posix/fnmatch_loop.c (FCT): Rerrange loop for skipping over rest
++	of a bracket expr not to run off the end of the string.
++	* posix/Makefile (tests): Add tst-fnmatch3.
++	* posix/tst-fnmatch3.c: New file.
++
++2015-04-29  Florian Weimer  <fweimer@redhat.com>
++
++	[BZ #18007]
++	* nss/nss_files/files-XXX.c (CONCAT): Always enable stayopen.
++	(CVE-2014-8121)
++	* nss/tst-nss-getpwent.c: New file.
++	* nss/Makefile (tests): Add new test.
++
++2015-02-22  Paul Pluzhnikov  <ppluzhnikov@google.com>
++
++	[BZ #17269]
++	* libio/wstrops.c (_IO_wstr_overflow): Guard against integer overflow
++	(enlarge_userbuf): Likewise.
++
++2015-02-26  Andreas Schwab  <schwab@suse.de>
++
++	[BZ #18032]
++	* posix/fnmatch_loop.c (FCT): Remove extra increment when skipping
++	over collating symbol inside a bracket expression.  Minor cleanup.
++
++2014-06-23  Andreas Schwab  <schwab@suse.de>
++
++	[BZ #17079]
++	* nss/nss_files/files-XXX.c (get_contents): Store overflow marker
++	before reading the next line.
++
++2015-10-02  Andreas Schwab  <schwab@suse.de>
++
++	* sysdeps/posix/getaddrinfo.c (gaih_inet): Advance address pointer
++	when skipping over non-matching result from nscd.
++
++2015-09-11  Alan Modra  <amodra@gmail.com>
++
++	[BZ #17153]
++	* elf/elf.h (DT_PPC64_NUM): Correct value.
++	* NEWS: Add to fixed bug list.
++
++2014-03-20  Andreas Schwab  <schwab@suse.de>
++
++	[BZ #16743]
++	* sysdeps/posix/getaddrinfo.c (gaih_inet): Properly skip over
++	non-matching result from nscd.
++
 +2015-04-21  Arjun Shankar  <arjun.is@lostca.se>
 +
 +	[BZ #18287]
@@ -347,10 +412,10 @@
  
  	[BZ #16529]
 diff --git a/NEWS b/NEWS
-index 98b479e..7f9388f 100644
+index 98b479e..2972c4a 100644
 --- a/NEWS
 +++ b/NEWS
-@@ -5,6 +5,59 @@ See the end for copying conditions.
+@@ -5,6 +5,65 @@ See the end for copying conditions.
  Please send GNU C library bug reports via <http://sourceware.org/bugzilla/>
  using `glibc' in the "product" field.
  
@@ -358,8 +423,9 @@
 +
 +* The following bugs are resolved with this release:
 +
-+  15946, 16545, 16574, 16623, 16657, 16695, 16878, 16882, 16885, 16916,
-+  16932, 16943, 16958, 17048, 17069, 17137, 17213, 17263, 17325, 17555,
++  15946, 16545, 16574, 16623, 16657, 16695, 16743, 16758, 16759, 16760,
++  16878, 16882, 16885, 16916, 16932, 16943, 16958, 17048, 17062, 17069,
++  17079, 17137, 17153, 17213, 17263, 17269, 17325, 17555, 18007, 18032,
 +  18287.
 +
 +* A buffer overflow in gethostbyname_r and related functions performing DNS
@@ -406,6 +472,11 @@
 +  IBM937, IBM939, IBM1364 could result in an out-of-bounds array read,
 +  resulting a denial-of-service security vulnerability in applications which
 +  use functions related to iconv. (CVE-2014-6040)
++
++* CVE-2014-8121 The NSS files backend would reset the file pointer used by
++  the get*ent functions if any of the query functions for the same database
++  are used during the iteration, causing a denial-of-service condition in
++  some applications.
 +
  Version 2.19
  
@@ -423,6 +494,19 @@
  ifeq (yes,$(build-shared))
  tests-static += tst-tls9-static
  tst-tls9-static-ENV = \
+diff --git a/elf/elf.h b/elf/elf.h
+index 40e87b2..78815e8 100644
+--- a/elf/elf.h
++++ b/elf/elf.h
+@@ -2283,7 +2283,7 @@ typedef Elf32_Addr Elf32_Conflict;
+ #define DT_PPC64_OPD	(DT_LOPROC + 1)
+ #define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
+ #define DT_PPC64_OPT	(DT_LOPROC + 3)
+-#define DT_PPC64_NUM    3
++#define DT_PPC64_NUM    4
+ 
+ /* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry.  */
+ #define PPC64_OPT_TLS		1
 diff --git a/elf/tst-dl-iter-static.c b/elf/tst-dl-iter-static.c
 new file mode 100644
 index 0000000..7303d7c
@@ -830,6 +914,67 @@
    attribute_hidden;
  
  libresolv_hidden_proto (_sethtent)
+diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
+index 62cdfda..f6d064d 100644
+--- a/inet/getnetgrent_r.c
++++ b/inet/getnetgrent_r.c
+@@ -235,6 +235,14 @@ endnetgrent (void)
+ }
+ 
+ #ifdef USE_NSCD
++static const char *
++get_nonempty_val (const char *in)
++{
++  if (*in == '\0')
++    return NULL;
++  return in;
++}
++
+ static enum nss_status
+ nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
+ 		  int *errnop)
+@@ -243,11 +251,11 @@ nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
+     return NSS_STATUS_UNAVAIL;
+ 
+   datap->type = triple_val;
+-  datap->val.triple.host = datap->cursor;
++  datap->val.triple.host = get_nonempty_val (datap->cursor);
+   datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
+-  datap->val.triple.user = datap->cursor;
++  datap->val.triple.user = get_nonempty_val (datap->cursor);
+   datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
+-  datap->val.triple.domain = datap->cursor;
++  datap->val.triple.domain = get_nonempty_val (datap->cursor);
+   datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
+ 
+   return NSS_STATUS_SUCCESS;
+diff --git a/libio/wstrops.c b/libio/wstrops.c
+index 399a377..9218d4a 100644
+--- a/libio/wstrops.c
++++ b/libio/wstrops.c
+@@ -95,8 +95,11 @@ _IO_wstr_overflow (fp, c)
+ 	  wchar_t *old_buf = fp->_wide_data->_IO_buf_base;
+ 	  size_t old_wblen = _IO_wblen (fp);
+ 	  _IO_size_t new_size = 2 * old_wblen + 100;
+-	  if (new_size < old_wblen)
++
++	  if (__glibc_unlikely (new_size < old_wblen)
++	      || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t)))
+ 	    return EOF;
++
+ 	  new_buf
+ 	    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
+ 									* sizeof (wchar_t));
+@@ -186,6 +189,9 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
+     return 1;
+ 
+   _IO_size_t newsize = offset + 100;
++  if (__glibc_unlikely (newsize > SIZE_MAX / sizeof (wchar_t)))
++    return 1;
++
+   wchar_t *oldbuf = wd->_IO_buf_base;
+   wchar_t *newbuf
+     = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
 diff --git a/locale/findlocale.c b/locale/findlocale.c
 index 0c42b99..faeee61 100644
 --- a/locale/findlocale.c
@@ -1668,7 +1813,7 @@
 +#define TEST_FUNCTION do_test ()
 +#include "../test-skeleton.c"
 diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
-index be01fe8..084f74d 100644
+index be01fe8..c61d10b 100644
 --- a/nscd/netgroupcache.c
 +++ b/nscd/netgroupcache.c
 @@ -202,12 +202,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
@@ -1685,9 +1830,46 @@
  		    if (status == NSS_STATUS_SUCCESS)
  		      {
  			if (data.type == triple_val)
-@@ -322,11 +317,18 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+@@ -216,6 +211,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 			    const char *nuser = data.val.triple.user;
+ 			    const char *ndomain = data.val.triple.domain;
+ 
++			    size_t hostlen = strlen (nhost ?: "") + 1;
++			    size_t userlen = strlen (nuser ?: "") + 1;
++			    size_t domainlen = strlen (ndomain ?: "") + 1;
++
+ 			    if (nhost == NULL || nuser == NULL || ndomain == NULL
+ 				|| nhost > nuser || nuser > ndomain)
+ 			      {
+@@ -233,9 +232,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 				     : last + strlen (last) + 1 - buffer);
+ 
+ 				/* We have to make temporary copies.  */
+-				size_t hostlen = strlen (nhost ?: "") + 1;
+-				size_t userlen = strlen (nuser ?: "") + 1;
+-				size_t domainlen = strlen (ndomain ?: "") + 1;
+ 				size_t needed = hostlen + userlen + domainlen;
+ 
+ 				if (buflen - req->key_len - bufused < needed)
+@@ -269,9 +265,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
  			      }
+ 
+ 			    char *wp = buffer + buffilled;
+-			    wp = stpcpy (wp, nhost) + 1;
+-			    wp = stpcpy (wp, nuser) + 1;
+-			    wp = stpcpy (wp, ndomain) + 1;
++			    wp = memmove (wp, nhost ?: "", hostlen);
++			    wp += hostlen;
++			    wp = memmove (wp, nuser ?: "", userlen);
++			    wp += userlen;
++			    wp = memmove (wp, ndomain ?: "", domainlen);
++			    wp += domainlen;
+ 			    buffilled = wp - buffer;
+ 			    ++nentries;
  			  }
+@@ -322,11 +321,18 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
+ 			      }
+ 			  }
  		      }
 -		    else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
 +		    else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
@@ -1705,6 +1887,69 @@
  		  }
  
  	      enum nss_status (*endfct) (struct __netgrent *);
+@@ -560,15 +566,19 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
+ 	{
+ 	  bool success = true;
+ 
+-	  if (host != NULL)
++	  /* For the host, user and domain in each triplet, we assume success
++	     if the value is blank because that is how the wildcard entry to
++	     match anything is stored in the netgroup cache.  */
++	  if (host != NULL && *triplets != '\0')
+ 	    success = strcmp (host, triplets) == 0;
+ 	  triplets = (const char *) rawmemchr (triplets, '\0') + 1;
+ 
+-	  if (success && user != NULL)
++	  if (success && user != NULL && *triplets != '\0')
+ 	    success = strcmp (user, triplets) == 0;
+ 	  triplets = (const char *) rawmemchr (triplets, '\0') + 1;
+ 
+-	  if (success && (domain == NULL || strcmp (domain, triplets) == 0))
++	  if (success && (domain == NULL || *triplets == '\0'
++			  || strcmp (domain, triplets) == 0))
+ 	    {
+ 	      dataset->resp.result = 1;
+ 	      break;
+diff --git a/nss/Makefile b/nss/Makefile
+index c8880c0..3f9d2d0 100644
+--- a/nss/Makefile
++++ b/nss/Makefile
+@@ -37,7 +37,7 @@ install-bin             := getent makedb
+ makedb-modules = xmalloc hash-string
+ extra-objs		+= $(makedb-modules:=.o)
+ 
+-tests			= test-netdb tst-nss-test1 test-digits-dots
++tests			= test-netdb tst-nss-test1 test-digits-dots tst-nss-getpwent
+ xtests			= bug-erange
+ 
+ include ../Makeconfig
+diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
+index 36242f9..3b90f7e 100644
+--- a/nss/nss_files/files-XXX.c
++++ b/nss/nss_files/files-XXX.c
+@@ -134,7 +134,7 @@ CONCAT(_nss_files_set,ENTNAME) (int stayopen)
+ 
+   __libc_lock_lock (lock);
+ 
+-  status = internal_setent (stayopen);
++  status = internal_setent (1);
+ 
+   if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
+     {
+@@ -198,10 +198,12 @@ get_contents (char *linebuf, size_t len, FILE *stream)
+     {
+       int curlen = ((remaining_len > (size_t) INT_MAX) ? INT_MAX
+ 		    : remaining_len);
+-      char *p = fgets_unlocked (curbuf, curlen, stream);
+ 
++      /* Terminate the line so that we can test for overflow.  */
+       ((unsigned char *) curbuf)[curlen - 1] = 0xff;
+ 
++      char *p = fgets_unlocked (curbuf, curlen, stream);
++
+       /* EOF or read error.  */
+       if (p == NULL)
+         return gcr_error;
 diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c
 index 34eae4c..bc0b367 100644
 --- a/nss/nss_files/files-netgrp.c
@@ -1718,6 +1963,130 @@
      }
    else
      {
+diff --git a/nss/tst-nss-getpwent.c b/nss/tst-nss-getpwent.c
+new file mode 100644
+index 0000000..f2e8abc
+--- /dev/null
++++ b/nss/tst-nss-getpwent.c
+@@ -0,0 +1,118 @@
++/* 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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <pwd.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++int
++do_test (void)
++{
++  /* Count the number of entries in the password database, and fetch
++     data from the first and last entries.  */
++  size_t count = 0;
++  struct passwd * pw;
++  char *first_name = NULL;
++  uid_t first_uid = 0;
++  char *last_name = NULL;
++  uid_t last_uid = 0;
++  setpwent ();
++  while ((pw  = getpwent ()) != NULL)
++    {
++      if (first_name == NULL)
++	{
++	  first_name = strdup (pw->pw_name);
++	  if (first_name == NULL)
++	    {
++	      printf ("strdup: %m\n");
++	      return 1;
++	    }
++	  first_uid = pw->pw_uid;
++	}
++
++      free (last_name);
++      last_name = strdup (pw->pw_name);
++      if (last_name == NULL)
++	{
++	  printf ("strdup: %m\n");
++	  return 1;
++	}
++      last_uid = pw->pw_uid;
++      ++count;
++    }
++  endpwent ();
++
++  if (count == 0)
++    {
++      printf ("No entries in the password database.\n");
++      return 0;
++    }
++
++  /* Try again, this time interleaving with name-based and UID-based
++     lookup operations.  The counts do not match if the interleaved
++     lookups affected the enumeration.  */
++  size_t new_count = 0;
++  setpwent ();
++  while ((pw  = getpwent ()) != NULL)
++    {
++      if (new_count == count)
++	{
++	  printf ("Additional entry in the password database.\n");
++	  return 1;
++	}
++      ++new_count;
++      struct passwd *pw2 = getpwnam (first_name);
++      if (pw2 == NULL)
++	{
++	  printf ("getpwnam (%s) failed: %m\n", first_name);
++	  return 1;
++	}
++      pw2 = getpwnam (last_name);
++      if (pw2 == NULL)
++	{
++	  printf ("getpwnam (%s) failed: %m\n", last_name);
++	  return 1;
++	}
++      pw2 = getpwuid (first_uid);
++      if (pw2 == NULL)
++	{
++	  printf ("getpwuid (%llu) failed: %m\n",
++		  (unsigned long long) first_uid);
++	  return 1;
++	}
++      pw2 = getpwuid (last_uid);
++      if (pw2 == NULL)
++	{
++	  printf ("getpwuid (%llu) failed: %m\n",
++		  (unsigned long long) last_uid);
++	  return 1;
++	}
++    }
++  endpwent ();
++  if (new_count < count)
++    {
++      printf ("Missing entry in the password database.\n");
++      return 1;
++    }
++
++  return 0;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
 diff --git a/po/eo.po b/po/eo.po
 index d01582d..f6ea766 100644
 --- a/po/eo.po
@@ -1937,7 +2306,7 @@
  #  endif
  # endif
 diff --git a/posix/Makefile b/posix/Makefile
-index 6709900..9dd5fa4 100644
+index 6709900..8f6e6b5 100644
 --- a/posix/Makefile
 +++ b/posix/Makefile
 @@ -86,7 +86,7 @@ tests		:= tstgetopt testfnm runtests runptests	     \
@@ -1945,7 +2314,7 @@
  		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
  		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
 -		   tst-pathconf tst-getaddrinfo4
-+		   tst-pathconf tst-getaddrinfo4 bug-regex36
++		   tst-pathconf tst-getaddrinfo4 bug-regex36 tst-fnmatch3
  xtests		:= bug-ga2
  ifeq (yes,$(build-shared))
  test-srcs	:= globtest
@@ -2006,6 +2375,66 @@
 +  regcomp (&r, "[a]\\|[a]\\{-2,}", 0);
 +  regfree (&r);
 +}
+diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c
+index f79d051..733cccb 100644
+--- a/posix/fnmatch_loop.c
++++ b/posix/fnmatch_loop.c
+@@ -899,11 +899,8 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
+ 
+ 	  matched:
+ 	    /* Skip the rest of the [...] that already matched.  */
+-	    do
++	    while ((c = *p++) != L (']'))
+ 	      {
+-	      ignore_next:
+-		c = *p++;
+-
+ 		if (c == L('\0'))
+ 		  /* [... (unterminated) loses.  */
+ 		  return FNM_NOMATCH;
+@@ -931,12 +928,11 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
+ 
+ 			if (c < L('a') || c >= L('z'))
+ 			  {
+-			    p = startp;
+-			    goto ignore_next;
++			    p = startp - 2;
++			    break;
+ 			  }
+ 		      }
+ 		    p += 2;
+-		    c = *p++;
+ 		  }
+ 		else if (c == L('[') && *p == L('='))
+ 		  {
+@@ -947,25 +943,21 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
+ 		    if (c != L('=') || p[1] != L(']'))
+ 		      return FNM_NOMATCH;
+ 		    p += 2;
+-		    c = *p++;
+ 		  }
+ 		else if (c == L('[') && *p == L('.'))
+ 		  {
+-		    ++p;
+ 		    while (1)
+ 		      {
+ 			c = *++p;
+-			if (c == '\0')
++			if (c == L('\0'))
+ 			  return FNM_NOMATCH;
+ 
+-			if (*p == L('.') && p[1] == L(']'))
++			if (c == L('.') && p[1] == L(']'))
+ 			  break;
+ 		      }
+ 		    p += 2;
+-		    c = *p++;
+ 		  }
+ 	      }
+-	    while (c != L(']'));
+ 	    if (not)
+ 	      return FNM_NOMATCH;
+ 	  }
 diff --git a/posix/regcomp.c b/posix/regcomp.c
 index 921d0f4..076eca3 100644
 --- a/posix/regcomp.c
@@ -2137,6 +2566,42 @@
        int oflag;
        mode_t mode;
      } open_action;
+diff --git a/posix/tst-fnmatch3.c b/posix/tst-fnmatch3.c
+new file mode 100644
+index 0000000..2a83c1b
+--- /dev/null
++++ b/posix/tst-fnmatch3.c
+@@ -0,0 +1,30 @@
++/* Test for fnmatch not reading past the end of the pattern.
++   Copyright (C) 2014 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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <fnmatch.h>
++
++int
++do_test (void)
++{
++  const char *pattern = "[[:alpha:]'[:alpha:]\0]";
++
++  return fnmatch (pattern, "a", 0) != FNM_NOMATCH;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
 diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c
 index 84cecf2..6cd874a 100644
 --- a/posix/tst-spawn.c
@@ -2701,6 +3166,29 @@
  	      res = do_sin (u, y, db, &cor);
  	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
  	      retval = ((res == res + cor) ? ((m) ? res : -res)
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index 8218237..d2283bc 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -712,6 +712,18 @@ gaih_inet (const char *name, const struct gaih_service *service,
+ 		    {
+ 		      socklen_t size = (air->family[i] == AF_INET
+ 					? INADDRSZ : IN6ADDRSZ);
++
++		      if (!((air->family[i] == AF_INET
++			     && req->ai_family == AF_INET6
++			     && (req->ai_flags & AI_V4MAPPED) != 0)
++			    || req->ai_family == AF_UNSPEC
++			    || air->family[i] == req->ai_family))
++			{
++			  /* Skip over non-matching result.  */
++			  addrs += size;
++			  continue;
++			}
++
+ 		      if (*pat == NULL)
+ 			{
+ 			  *pat = addrfree++;
 diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h
 index 76ead1d..30553c1 100644
 --- a/sysdeps/powerpc/powerpc64/entry.h
Index: debian/patches/amd64/local-blacklist-on-TSX-Haswell.diff
===================================================================
--- debian/patches/amd64/local-blacklist-on-TSX-Haswell.diff	(révision 6511)
+++ debian/patches/amd64/local-blacklist-on-TSX-Haswell.diff	(nonexistent)
@@ -1,88 +0,0 @@
-Intel TSX is broken on Haswell based processors (erratum HSD136/HSW136)
-and a microcode update is available to simply disable the corresponding
-instructions.
-
-While the responsability to continue or not using TSX should be left to
-the users, a live microcode update will disable the TSX instructions
-causing already started binaries to segfault. This patch simply disable 
-Intel TSX (HLE and RTM) on processors which might receive a microcode
-update, so that it doesn't happen. We might expect newer steppings to
-fix the issue, and if it is not the case the corresponding processors 
-will be shipped with TSX already disabled.
-
-Author: Henrique de Moraes Holschuh <hmh@debian.org>
-
-diff --git a/sysdeps/x86_64/multiarch/init-arch.c b/sysdeps/x86_64/multiarch/init-arch.c
-index db74d97..6f61ae6 100644
---- a/sysdeps/x86_64/multiarch/init-arch.c
-+++ b/sysdeps/x86_64/multiarch/init-arch.c
-@@ -26,7 +26,7 @@ struct cpu_features __cpu_features attribute_hidden;
- 
- 
- static void
--get_common_indeces (unsigned int *family, unsigned int *model)
-+get_common_indeces (unsigned int *family, unsigned int *model, unsigned int *stepping)
- {
-   __cpuid (1, __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax,
- 	   __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx,
-@@ -36,6 +36,7 @@ get_common_indeces (unsigned int *family, unsigned int *model)
-   unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax;
-   *family = (eax >> 8) & 0x0f;
-   *model = (eax >> 4) & 0x0f;
-+  *stepping = eax & 0x0f;
- }
- 
- 
-@@ -47,6 +48,7 @@ __init_cpu_features (void)
-   unsigned int edx;
-   unsigned int family = 0;
-   unsigned int model = 0;
-+  unsigned int stepping = 0;
-   enum cpu_features_kind kind;
- 
-   __cpuid (0, __cpu_features.max_cpuid, ebx, ecx, edx);
-@@ -56,7 +58,7 @@ __init_cpu_features (void)
-     {
-       kind = arch_kind_intel;
- 
--      get_common_indeces (&family, &model);
-+      get_common_indeces (&family, &model, &stepping);
- 
-       unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax;
-       unsigned int extended_family = (eax >> 20) & 0xff;
-@@ -131,7 +133,7 @@ __init_cpu_features (void)
-     {
-       kind = arch_kind_amd;
- 
--      get_common_indeces (&family, &model);
-+      get_common_indeces (&family, &model, &stepping);
- 
-       ecx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx;
- 
-@@ -176,6 +178,14 @@ __init_cpu_features (void)
- 	}
-     }
- 
-+  /* Disable Intel TSX (HLE and RTM) due to erratum HSD136/HSW136
-+     on Haswell processors, to work around outdated microcode that
-+     doesn't disable the broken feature by default */
-+  if (kind == arch_kind_intel && family == 6 &&
-+      ((model == 63 && stepping <= 2) || (model == 60 && stepping <= 3) ||
-+       (model == 69 && stepping <= 1) || (model == 70 && stepping <= 1)))
-+    __cpu_features.cpuid[COMMON_CPUID_INDEX_7].ebx &= ~(bit_RTM | bit_HLE);
-+
-   __cpu_features.family = family;
-   __cpu_features.model = model;
-   atomic_write_barrier ();
-diff --git a/sysdeps/x86_64/multiarch/init-arch.h b/sysdeps/x86_64/multiarch/init-arch.h
-index 793707a..e2745cb 100644
---- a/sysdeps/x86_64/multiarch/init-arch.h
-+++ b/sysdeps/x86_64/multiarch/init-arch.h
-@@ -40,6 +40,7 @@
- 
- /* COMMON_CPUID_INDEX_7.  */
- #define bit_RTM		(1 << 11)
-+#define bit_HLE		(1 << 4)
- 
- /* XCR0 Feature flags.  */
- #define bit_XMM_state  (1 << 1)
Index: debian/patches/amd64/local-blacklist-for-Intel-TSX.diff
===================================================================
--- debian/patches/amd64/local-blacklist-for-Intel-TSX.diff	(nonexistent)
+++ debian/patches/amd64/local-blacklist-for-Intel-TSX.diff	(révision 6826)
@@ -0,0 +1,99 @@
+Intel TSX is broken on Haswell based processors (erratum HSD136/HSW136)
+and a microcode update is available to simply disable the corresponding
+instructions.
+
+A live microcode update will disable the TSX instructions causing
+already started binaries to segfault. This patch simply disable Intel
+TSX (HLE and RTM) on processors which might receive a microcode update,
+so that it doesn't happen.  We might expect newer steppings to fix the
+issue (e.g. as Haswell-EX did).
+
+Intel TSX-NI is also broken on Broadwell systems, and documented as
+being unavailable in their specification updates errata list.  However,
+some end-user systems were shipped with old microcode that left Intel
+TSX-NI still enabled in CPUID on these processors.  We must not allow
+RTM to be used by glibc on these systems, due to runtime system
+misbehavior and live-update of microcode hazards.
+
+Author: Henrique de Moraes Holschuh <hmh@debian.org>
+
+--- a/sysdeps/x86_64/multiarch/init-arch.c
++++ b/sysdeps/x86_64/multiarch/init-arch.c
+@@ -26,7 +26,7 @@
+ 
+ 
+ static void
+-get_common_indeces (unsigned int *family, unsigned int *model)
++get_common_indeces (unsigned int *family, unsigned int *model, unsigned int *stepping)
+ {
+   __cpuid (1, __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax,
+ 	   __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx,
+@@ -36,6 +36,7 @@
+   unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax;
+   *family = (eax >> 8) & 0x0f;
+   *model = (eax >> 4) & 0x0f;
++  *stepping = eax & 0x0f;
+ }
+ 
+ 
+@@ -47,6 +48,7 @@
+   unsigned int edx;
+   unsigned int family = 0;
+   unsigned int model = 0;
++  unsigned int stepping = 0;
+   enum cpu_features_kind kind;
+ 
+   __cpuid (0, __cpu_features.max_cpuid, ebx, ecx, edx);
+@@ -56,7 +58,7 @@
+     {
+       kind = arch_kind_intel;
+ 
+-      get_common_indeces (&family, &model);
++      get_common_indeces (&family, &model, &stepping);
+ 
+       unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax;
+       unsigned int extended_family = (eax >> 20) & 0xff;
+@@ -131,7 +133,7 @@
+     {
+       kind = arch_kind_amd;
+ 
+-      get_common_indeces (&family, &model);
++      get_common_indeces (&family, &model, &stepping);
+ 
+       ecx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx;
+ 
+@@ -176,6 +178,24 @@
+ 	}
+     }
+ 
++  /* Disable Intel TSX (HLE and RTM) due to erratum HSD136/HSW136
++     on all Haswell processors, except Haswell-EX/Xeon E7-v3 (306F4),
++     to work around outdated microcode that doesn't disable the
++     broken feature by default.
++
++     Disable TSX on Broadwell, due to errata BDM53/BDW51/BDD51/
++     BDE42.  The errata documentation states that RTM is unusable,
++     and that it should not be advertised by CPUID at all on any
++     such processors.  Unfortunately, it _is_ advertised in some
++     (older) microcode versions.  Exceptions: Broadwell-E (406Fx),
++     likely already fixed at launch */
++  if (kind == arch_kind_intel && family == 6 &&
++      ((model == 63 && stepping <= 2) || (model == 60 && stepping <= 3) ||
++       (model == 69 && stepping <= 1) || (model == 70 && stepping <= 1) ||
++       (model == 61 && stepping <= 4) || (model == 71 && stepping <= 1) ||
++       (model == 86 && stepping <= 2) ))
++    __cpu_features.cpuid[COMMON_CPUID_INDEX_7].ebx &= ~(bit_RTM | bit_HLE);
++
+   __cpu_features.family = family;
+   __cpu_features.model = model;
+   atomic_write_barrier ();
+--- a/sysdeps/x86_64/multiarch/init-arch.h
++++ b/sysdeps/x86_64/multiarch/init-arch.h
+@@ -40,6 +40,7 @@
+ 
+ /* COMMON_CPUID_INDEX_7.  */
+ #define bit_RTM		(1 << 11)
++#define bit_HLE		(1 << 4)
+ 
+ /* XCR0 Feature flags.  */
+ #define bit_XMM_state  (1 << 1)
Index: debian/patches/any/cvs-ld_pointer_guard.diff
===================================================================
--- debian/patches/any/cvs-ld_pointer_guard.diff	(nonexistent)
+++ debian/patches/any/cvs-ld_pointer_guard.diff	(révision 6826)
@@ -0,0 +1,62 @@
+2015-10-15  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #18928]
+	* sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Remove
+	_dl_pointer_guard member.
+	* elf/rtld.c (_rtld_global_ro): Remove _dl_pointer_guard
+	initializer.
+	(security_init): Always set up pointer guard.
+	(process_envvars): Do not process LD_POINTER_GUARD.
+
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -162,7 +162,6 @@
+     ._dl_hwcap_mask = HWCAP_IMPORTANT,
+     ._dl_lazy = 1,
+     ._dl_fpu_control = _FPU_DEFAULT,
+-    ._dl_pointer_guard = 1,
+     ._dl_pagesize = EXEC_PAGESIZE,
+     ._dl_inhibit_cache = 0,
+ 
+@@ -857,15 +856,12 @@
+ #endif
+ 
+   /* Set up the pointer guard as well, if necessary.  */
+-  if (GLRO(dl_pointer_guard))
+-    {
+-      uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
+-							     stack_chk_guard);
++  uintptr_t pointer_chk_guard
++    = _dl_setup_pointer_guard (_dl_random, stack_chk_guard);
+ #ifdef THREAD_SET_POINTER_GUARD
+-      THREAD_SET_POINTER_GUARD (pointer_chk_guard);
++  THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+ #endif
+-      __pointer_chk_guard_local = pointer_chk_guard;
+-    }
++  __pointer_chk_guard_local = pointer_chk_guard;
+ 
+   /* We do not need the _dl_random value anymore.  The less
+      information we leave behind, the better, so clear the
+@@ -2607,9 +2603,6 @@
+ 	      GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
+ 	      break;
+ 	    }
+-
+-	  if (memcmp (envline, "POINTER_GUARD", 13) == 0)
+-	    GLRO(dl_pointer_guard) = envline[14] != '0';
+ 	  break;
+ 
+ 	case 14:
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -591,9 +591,6 @@
+   /* List of auditing interfaces.  */
+   struct audit_ifaces *_dl_audit;
+   unsigned int _dl_naudit;
+-
+-  /* 0 if internal pointer values should not be guarded, 1 if they should.  */
+-  EXTERN int _dl_pointer_guard;
+ };
+ # define __rtld_global_attribute__
+ # ifdef IS_IN_rtld
Index: debian/patches/any/cvs-mangle-tls_dtor_list.diff
===================================================================
--- debian/patches/any/cvs-mangle-tls_dtor_list.diff	(nonexistent)
+++ debian/patches/any/cvs-mangle-tls_dtor_list.diff	(révision 6826)
@@ -0,0 +1,35 @@
+2015-10-06  Florian Weimer  <fweimer@redhat.com>
+
+	[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.
+
+--- a/stdlib/cxa_thread_atexit_impl.c
++++ b/stdlib/cxa_thread_atexit_impl.c
+@@ -42,6 +42,10 @@
+ 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;
+@@ -83,9 +87,13 @@
+   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);
+ 
+       __rtld_lock_lock_recursive (GL(dl_load_lock));
+ 
Index: debian/patches/any/cvs-strxfrm-buffer-overflows.diff
===================================================================
--- debian/patches/any/cvs-strxfrm-buffer-overflows.diff	(nonexistent)
+++ debian/patches/any/cvs-strxfrm-buffer-overflows.diff	(révision 6826)
@@ -0,0 +1,670 @@
+2015-01-13  Leonhard Holz  <leonhard.holz@web.de>
+
+	[BZ #16009]
+	* string/strxfrm_l.c (STRXFRM): Allocate fixed size cache for
+	weights and rules. Use do_xfrm_cached if data fits in cache,
+	do_xfrm otherwise.  Moved former main loop to...
+	* (do_xfrm_cached): New function.
+	* (do_xfrm): Non-caching version of do_xfrm_cached. Uses
+	find_idx, find_position and stack_push.
+	* (find_idx): New function.
+	* (find_position): Likewise.
+	* localedata/sort-test.sh: Added test run for do_xfrm.
+	* localedata/xfrm-test.c (main): Added command line option
+	-nocache to run the test with strings that are too large for
+	the STRXFRM cache.
+
+--- a/localedata/sort-test.sh
++++ b/localedata/sort-test.sh
+@@ -49,11 +49,17 @@
+    ${common_objpfx}localedata/xfrm-test $id < $cns.in \
+    > ${common_objpfx}localedata/$cns.xout || here=1
+   cmp -s $cns.in ${common_objpfx}localedata/$cns.xout || here=1
++  LOCPATH=${common_objpfx}localedata GCONV_PATH=${common_objpfx}/iconvdata \
++   LC_ALL=$l ${run_program_prefix} \
++   ${common_objpfx}localedata/xfrm-test $id -nocache < $cns.in \
++   > ${common_objpfx}localedata/$cns.nocache.xout || here=1
++  cmp -s $cns.in ${common_objpfx}localedata/$cns.nocache.xout || here=1
+   if test $here -eq 0; then
+     echo "$l xfrm-test OK"
+   else
+     echo "$l xfrm-test FAIL"
+     diff -u $cns.in ${common_objpfx}localedata/$cns.xout | sed 's/^/  /'
++    diff -u $cns.in ${common_objpfx}localedata/$cns.nocache.xout | sed 's/^/  /'
+     status=1
+   fi
+ done
+--- a/localedata/xfrm-test.c
++++ b/localedata/xfrm-test.c
+@@ -23,7 +23,10 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <stdbool.h>
+ 
++/* Keep in sync with string/strxfrm_l.c.  */
++#define SMALL_STR_SIZE 4095
+ 
+ struct lines
+ {
+@@ -37,6 +40,7 @@
+ main (int argc, char *argv[])
+ {
+   int result = 0;
++  bool nocache = false;
+   size_t nstrings, nstrings_max;
+   struct lines *strings;
+   char *line = NULL;
+@@ -44,7 +48,18 @@
+   size_t n;
+ 
+   if (argc < 2)
+-    error (1, 0, "usage: %s <random seed>", argv[0]);
++    error (1, 0, "usage: %s <random seed> [-nocache]", argv[0]);
++
++  if (argc == 3)
++    {
++      if (strcmp (argv[2], "-nocache") == 0)
++	nocache = true;
++      else
++	{
++	  printf ("Unknown option %s!\n", argv[2]);
++	  exit (1);
++	}
++    }
+ 
+   setlocale (LC_ALL, "");
+ 
+@@ -59,9 +74,9 @@
+ 
+   while (1)
+     {
+-      char saved, *newp;
+-      int needed;
+-      int l;
++      char saved, *word, *newp;
++      size_t l, line_len, needed;
++
+       if (getline (&line, &len, stdin) < 0)
+ 	break;
+ 
+@@ -83,10 +98,35 @@
+ 
+       saved = line[l];
+       line[l] = '\0';
+-      needed = strxfrm (NULL, line, 0);
++
++      if (nocache)
++	{
++	  line_len = strlen (line);
++	  word = malloc (line_len + SMALL_STR_SIZE + 1);
++	  if (word == NULL)
++	    {
++	      printf ("malloc failed: %m\n");
++	      exit (1);
++	    }
++	  memset (word, ' ', SMALL_STR_SIZE);
++	  memcpy (word + SMALL_STR_SIZE, line, line_len);
++	  word[line_len + SMALL_STR_SIZE] = '\0';
++	}
++      else
++        word = line;
++
++      needed = strxfrm (NULL, word, 0);
+       newp = malloc (needed + 1);
+-      strxfrm (newp, line, needed + 1);
++      if (newp == NULL)
++	{
++	  printf ("malloc failed: %m\n");
++	  exit (1);
++	}
++      strxfrm (newp, word, needed + 1);
+       strings[nstrings].xfrm = newp;
++
++      if (nocache)
++	free (word);
+       line[l] = saved;
+       ++nstrings;
+     }
+--- a/string/strxfrm_l.c
++++ b/string/strxfrm_l.c
+@@ -40,8 +40,23 @@
+ #define CONCAT(a,b) CONCAT1(a,b)
+ #define CONCAT1(a,b) a##b
+ 
++/* Maximum string size that is calculated with cached indices.  Right now this
++   is an arbitrary value open to optimizations.  SMALL_STR_SIZE * 4 has to be
++   lower than __MAX_ALLOCA_CUTOFF.  Keep localedata/xfrm-test.c in sync.  */
++#define SMALL_STR_SIZE 4095
++
+ #include "../locale/localeinfo.h"
+ 
++/* Group locale data for shorter parameter lists.  */
++typedef struct
++{
++  uint_fast32_t nrules;
++  unsigned char *rulesets;
++  USTRING_TYPE *weights;
++  int32_t *table;
++  USTRING_TYPE *extra;
++  int32_t *indirect;
++} locale_data_t;
+ 
+ #ifndef WIDE_CHAR_VERSION
+ 
+@@ -80,115 +95,328 @@
+ }
+ #endif
+ 
++/* Find next weight and rule index.  Inlined since called for every char.  */
++static __always_inline size_t
++find_idx (const USTRING_TYPE **us, int32_t *weight_idx,
++	  unsigned char *rule_idx, const locale_data_t *l_data, const int pass)
++{
++  const int32_t *table = l_data->table;
++  const int32_t *indirect = l_data->indirect;
++  const USTRING_TYPE *extra = l_data->extra;
++#include WEIGHT_H
++  int32_t tmp = findidx (us, -1);
++  *rule_idx = tmp >> 24;
++  int32_t idx = tmp & 0xffffff;
++  size_t len = l_data->weights[idx++];
+ 
+-size_t
+-STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
++  /* Skip over indices of previous levels.  */
++  for (int i = 0; i < pass; i++)
++    {
++      idx += len;
++      len = l_data->weights[idx++];
++    }
++
++  *weight_idx = idx;
++  return len;
++}
++
++static int
++find_position (const USTRING_TYPE *us, const locale_data_t *l_data,
++	       const int pass)
+ {
+-  struct __locale_data *current = l->__locales[LC_COLLATE];
+-  uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
+-  /* We don't assign the following values right away since it might be
+-     unnecessary in case there are no rules.  */
+-  const unsigned char *rulesets;
+-  const int32_t *table;
+-  const USTRING_TYPE *weights;
+-  const USTRING_TYPE *extra;
+-  const int32_t *indirect;
++  int32_t weight_idx;
++  unsigned char rule_idx;
++  const USTRING_TYPE *usrc = us;
++
++  find_idx (&usrc, &weight_idx, &rule_idx, l_data, pass);
++  return l_data->rulesets[rule_idx * l_data->nrules + pass] & sort_position;
++}
++
++/* Do the transformation.  */
++static size_t
++do_xfrm (const USTRING_TYPE *usrc, STRING_TYPE *dest, size_t n,
++	 const locale_data_t *l_data)
++{
++  int32_t weight_idx;
++  unsigned char rule_idx;
+   uint_fast32_t pass;
+-  size_t needed;
++  size_t needed = 0;
+   size_t last_needed;
+-  const USTRING_TYPE *usrc;
+-  size_t srclen = STRLEN (src);
+-  int32_t *idxarr;
+-  unsigned char *rulearr;
+-  size_t idxmax;
+-  size_t idxcnt;
+-  int use_malloc;
+ 
+-#include WEIGHT_H
+-
+-  if (nrules == 0)
++  /* Now the passes over the weights.  */
++  for (pass = 0; pass < l_data->nrules; ++pass)
+     {
+-      if (n != 0)
+-	STPNCPY (dest, src, MIN (srclen + 1, n));
++      size_t backw_len = 0;
++      last_needed = needed;
++      const USTRING_TYPE *cur = usrc;
++      const USTRING_TYPE *backw_start = NULL;
+ 
+-      return srclen;
+-    }
++       /* We assume that if a rule has defined `position' in one section
++         this is true for all of them.  */
++      int position = find_position (cur, l_data, pass);
+ 
+-  rulesets = (const unsigned char *)
+-    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
+-  table = (const int32_t *)
+-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
+-  weights = (const USTRING_TYPE *)
+-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
+-  extra = (const USTRING_TYPE *)
+-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
+-  indirect = (const int32_t *)
+-    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
+-  use_malloc = 0;
++      if (position == 0)
++	{
++	  while (*cur != L('\0'))
++	    {
++	      const USTRING_TYPE *pos = cur;
++	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
++				     pass);
++	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
+ 
+-  assert (((uintptr_t) table) % __alignof__ (table[0]) == 0);
+-  assert (((uintptr_t) weights) % __alignof__ (weights[0]) == 0);
+-  assert (((uintptr_t) extra) % __alignof__ (extra[0]) == 0);
+-  assert (((uintptr_t) indirect) % __alignof__ (indirect[0]) == 0);
++	      if ((rule & sort_forward) != 0)
++		{
++		  /* Handle the pushed backward sequence.  */
++		  if (backw_start != NULL)
++		    {
++		      for (size_t i = backw_len; i > 0; )
++			{
++			  int32_t weight_idx;
++			  unsigned char rule_idx;
++			  size_t len = find_idx (&backw_start, &weight_idx,
++						 &rule_idx, l_data, pass);
++			  if (needed + i < n)
++			    for (size_t j = len; j > 0; j--)
++			      dest[needed + i - j] =
++				l_data->weights[weight_idx++];
+ 
+-  /* Handle an empty string as a special case.  */
+-  if (srclen == 0)
+-    {
+-      if (n != 0)
+-	*dest = L('\0');
+-      return 0;
+-    }
++			  i -= len;
++			}
+ 
+-  /* We need the elements of the string as unsigned values since they
+-     are used as indeces.  */
+-  usrc = (const USTRING_TYPE *) src;
++		      needed += backw_len;
++		      backw_start = NULL;
++		      backw_len = 0;
++		    }
+ 
+-  /* Perform the first pass over the string and while doing this find
+-     and store the weights for each character.  Since we want this to
+-     be as fast as possible we are using `alloca' to store the temporary
+-     values.  But since there is no limit on the length of the string
+-     we have to use `malloc' if the string is too long.  We should be
+-     very conservative here.  */
+-  if (! __libc_use_alloca ((srclen + 1) * (sizeof (int32_t) + 1)))
+-    {
+-      idxarr = (int32_t *) malloc ((srclen + 1) * (sizeof (int32_t) + 1));
+-      rulearr = (unsigned char *) &idxarr[srclen];
++		  /* Now handle the forward element.  */
++		  if (needed + len < n)
++		    while (len-- > 0)
++		      dest[needed++] = l_data->weights[weight_idx++];
++		  else
++		    /* No more characters fit into the buffer.  */
++		    needed += len;
++		}
++	      else
++		{
++		  /* Remember start of the backward sequence & track length.  */
++		  if (backw_start == NULL)
++		    backw_start = pos;
++		  backw_len += len;
++		}
++	    }
+ 
+-      if (idxarr == NULL)
+-	/* No memory.  Well, go with the stack then.
+ 
+-	   XXX Once this implementation is stable we will handle this
+-	   differently.  Instead of precomputing the indeces we will
+-	   do this in time.  This means, though, that this happens for
+-	   every pass again.  */
+-	goto try_stack;
+-      use_malloc = 1;
+-    }
+-  else
+-    {
+-    try_stack:
+-      idxarr = (int32_t *) alloca (srclen * sizeof (int32_t));
+-      rulearr = (unsigned char *) alloca (srclen + 1);
++	  /* Handle the pushed backward sequence.  */
++	  if (backw_start != NULL)
++	    {
++	      for (size_t i = backw_len; i > 0; )
++		{
++		  size_t len = find_idx (&backw_start, &weight_idx, &rule_idx,
++					 l_data, pass);
++		  if (needed + i < n)
++		    for (size_t j = len; j > 0; j--)
++		      dest[needed + i - j] =
++			l_data->weights[weight_idx++];
++
++		  i -= len;
++		}
++
++	      needed += backw_len;
++	    }
++	}
++      else
++	{
++	  int val = 1;
++#ifndef WIDE_CHAR_VERSION
++	  char buf[7];
++	  size_t buflen;
++#endif
++	  size_t i;
++
++	  while (*cur != L('\0'))
++	    {
++	      const USTRING_TYPE *pos = cur;
++	      size_t len = find_idx (&cur, &weight_idx, &rule_idx, l_data,
++				     pass);
++	      int rule = l_data->rulesets[rule_idx * l_data->nrules + pass];
++
++	      if ((rule & sort_forward) != 0)
++		{
++		  /* Handle the pushed backward sequence.  */
++		  if (backw_start != NULL)
++		    {
++		      for (size_t p = backw_len; p > 0; p--)
++			{
++			  size_t len;
++			  int32_t weight_idx;
++			  unsigned char rule_idx;
++			  const USTRING_TYPE *backw_cur = backw_start;
++
++			  /* To prevent a warning init the used vars.  */
++			  len = find_idx (&backw_cur, &weight_idx,
++					  &rule_idx, l_data, pass);
++
++			  for (i = 1; i < p; i++)
++			    len = find_idx (&backw_cur, &weight_idx,
++					    &rule_idx, l_data, pass);
++
++			  if (len != 0)
++			    {
++#ifdef WIDE_CHAR_VERSION
++			      if (needed + 1 + len < n)
++				{
++				  dest[needed] = val;
++				  for (i = 0; i < len; ++i)
++				    dest[needed + 1 + i] =
++				      l_data->weights[weight_idx + i];
++				}
++			      needed += 1 + len;
++#else
++			      buflen = utf8_encode (buf, val);
++			      if (needed + buflen + len < n)
++				{
++				  for (i = 0; i < buflen; ++i)
++				    dest[needed + i] = buf[i];
++				  for (i = 0; i < len; ++i)
++				    dest[needed + buflen + i] =
++				      l_data->weights[weight_idx + i];
++				}
++			      needed += buflen + len;
++#endif
++			      val = 1;
++			    }
++			  else
++			    ++val;
++			}
++
++		      backw_start = NULL;
++		      backw_len = 0;
++		    }
++
++		  /* Now handle the forward element.  */
++		  if (len != 0)
++		    {
++#ifdef WIDE_CHAR_VERSION
++		      if (needed + 1 + len < n)
++			{
++			  dest[needed] = val;
++			  for (i = 0; i < len; ++i)
++			    dest[needed + 1 + i] =
++			      l_data->weights[weight_idx + i];
++			}
++		      needed += 1 + len;
++#else
++		      buflen = utf8_encode (buf, val);
++		      if (needed + buflen + len < n)
++			{
++			  for (i = 0; i < buflen; ++i)
++			    dest[needed + i] = buf[i];
++			  for (i = 0; i < len; ++i)
++			    dest[needed + buflen + i] =
++			      l_data->weights[weight_idx + i];
++			}
++		      needed += buflen + len;
++#endif
++		      val = 1;
++		    }
++		  else
++		    ++val;
++		}
++	      else
++		{
++		  /* Remember start of the backward sequence & track length.  */
++		  if (backw_start == NULL)
++		    backw_start = pos;
++		  backw_len++;
++		}
++	    }
++
++	  /* Handle the pushed backward sequence.  */
++	  if (backw_start != NULL)
++	    {
++	      for (size_t p = backw_len; p > 0; p--)
++		{
++		  size_t len;
++		  int32_t weight_idx;
++		  unsigned char rule_idx;
++		  const USTRING_TYPE *backw_cur = backw_start;
++
++		  /* To prevent a warning init the used vars.  */
++		  len = find_idx (&backw_cur, &weight_idx,
++				  &rule_idx, l_data, pass);
++
++		  for (i = 1; i < p; i++)
++		    len = find_idx (&backw_cur, &weight_idx,
++				    &rule_idx, l_data, pass);
++
++		  if (len != 0)
++		    {
++#ifdef WIDE_CHAR_VERSION
++		      if (needed + 1 + len < n)
++			{
++			  dest[needed] = val;
++			  for (i = 0; i < len; ++i)
++			    dest[needed + 1 + i] =
++			      l_data->weights[weight_idx + i];
++			}
++		      needed += 1 + len;
++#else
++		      buflen = utf8_encode (buf, val);
++		      if (needed + buflen + len < n)
++			{
++			  for (i = 0; i < buflen; ++i)
++			    dest[needed + i] = buf[i];
++			  for (i = 0; i < len; ++i)
++			    dest[needed + buflen + i] =
++			      l_data->weights[weight_idx + i];
++			}
++		      needed += buflen + len;
++#endif
++		      val = 1;
++		    }
++		  else
++		    ++val;
++		}
++	    }
++	}
++
++      /* Finally store the byte to separate the passes or terminate
++	 the string.  */
++      if (needed < n)
++	dest[needed] = pass + 1 < l_data->nrules ? L('\1') : L('\0');
++      ++needed;
+     }
+ 
+-  idxmax = 0;
+-  do
++  /* This is a little optimization: many collation specifications have
++     a `position' rule at the end and if no non-ignored character
++     is found the last \1 byte is immediately followed by a \0 byte
++     signalling this.  We can avoid the \1 byte(s).  */
++  if (needed > 2 && needed == last_needed + 1)
+     {
+-      int32_t tmp = findidx (&usrc, -1);
+-      rulearr[idxmax] = tmp >> 24;
+-      idxarr[idxmax] = tmp & 0xffffff;
+-
+-      ++idxmax;
++      /* Remove the \1 byte.  */
++      if (--needed <= n)
++	dest[needed - 1] = L('\0');
+     }
+-  while (*usrc != L('\0'));
+ 
+-  /* This element is only read, the value never used but to determine
+-     another value which then is ignored.  */
+-  rulearr[idxmax] = '\0';
++  /* Return the number of bytes/words we need, but don't count the NUL
++     byte/word at the end.  */
++  return needed - 1;
++}
++
++/* Do the transformation using weight-index and rule cache.  */
++static size_t
++do_xfrm_cached (STRING_TYPE *dest, size_t n, const locale_data_t *l_data,
++		size_t idxmax, int32_t *idxarr, const unsigned char *rulearr)
++{
++  uint_fast32_t nrules = l_data->nrules;
++  unsigned char *rulesets = l_data->rulesets;
++  USTRING_TYPE *weights = l_data->weights;
++  uint_fast32_t pass;
++  size_t needed = 0;
++  size_t last_needed;
++  size_t idxcnt;
+ 
+-  /* Now the passes over the weights.  We now use the indeces we found
+-     before.  */
+-  needed = 0;
++  /* Now the passes over the weights.  */
+   for (pass = 0; pass < nrules; ++pass)
+     {
+       size_t backw_stop = ~0ul;
+@@ -434,14 +662,93 @@
+ 	dest[needed - 1] = L('\0');
+     }
+ 
+-  /* Free the memory if needed.  */
+-  if (use_malloc)
+-    free (idxarr);
+-
+   /* Return the number of bytes/words we need, but don't count the NUL
+      byte/word at the end.  */
+   return needed - 1;
+ }
++
++size_t
++STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
++{
++  locale_data_t l_data;
++  struct __locale_data *current = l->__locales[LC_COLLATE];
++  const int32_t *table;
++  const int32_t *indirect;
++  const USTRING_TYPE *extra;
++#include WEIGHT_H
++  l_data.nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
++
++  /* Handle byte comparison case.  */
++  if (l_data.nrules == 0)
++    {
++      size_t srclen = STRLEN (src);
++
++      if (n != 0)
++	STPNCPY (dest, src, MIN (srclen + 1, n));
++
++      return srclen;
++    }
++
++  /* Handle an empty string, code hereafter relies on strlen (src) > 0.  */
++  if (*src == L('\0'))
++    {
++      if (n != 0)
++	*dest = L('\0');
++      return 0;
++    }
++
++  /* Get the locale data.  */
++  l_data.rulesets = (unsigned char *)
++    current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULESETS)].string;
++  l_data.table = (int32_t *)
++    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_TABLE,SUFFIX))].string;
++  l_data.weights = (USTRING_TYPE *)
++    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_WEIGHT,SUFFIX))].string;
++  l_data.extra = (USTRING_TYPE *)
++    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string;
++  l_data.indirect = (int32_t *)
++    current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string;
++  table = l_data.table;
++  indirect = l_data.indirect;
++  extra = l_data.extra;
++
++  assert (((uintptr_t) l_data.table) % __alignof__ (l_data.table[0]) == 0);
++  assert (((uintptr_t) l_data.weights) % __alignof__ (l_data.weights[0]) == 0);
++  assert (((uintptr_t) l_data.extra) % __alignof__ (l_data.extra[0]) == 0);
++  assert (((uintptr_t) l_data.indirect) % __alignof__ (l_data.indirect[0]) == 0);
++
++  /* We need the elements of the string as unsigned values since they
++     are used as indeces.  */
++  const USTRING_TYPE *usrc = (const USTRING_TYPE *) src;
++
++  /* Allocate cache for small strings on the stack and fill it with weight and
++     rule indices.  If the cache size is not sufficient, continue with the
++     uncached xfrm version.  */
++  size_t idxmax = 0;
++  const USTRING_TYPE *cur = usrc;
++  int32_t *idxarr = alloca (SMALL_STR_SIZE * sizeof (int32_t));
++  unsigned char *rulearr = alloca (SMALL_STR_SIZE + 1);
++
++  do
++    {
++      int32_t tmp = findidx (&cur, -1);
++      rulearr[idxmax] = tmp >> 24;
++      idxarr[idxmax] = tmp & 0xffffff;
++
++      ++idxmax;
++    }
++  while (*cur != L('\0') && idxmax < SMALL_STR_SIZE);
++
++  /* This element is only read, the value never used but to determine
++     another value which then is ignored.  */
++  rulearr[idxmax] = '\0';
++
++  /* Do the transformation.  */
++  if (*cur == L('\0'))
++    return do_xfrm_cached (dest, n, &l_data, idxmax, idxarr, rulearr);
++  else
++    return do_xfrm (usrc, dest, n, &l_data);
++}
+ libc_hidden_def (STRXFRM)
+ 
+ #ifndef WIDE_CHAR_VERSION
Index: debian/patches/series
===================================================================
--- debian/patches/series	(révision 6511)
+++ debian/patches/series	(copie de travail)
@@ -49,7 +49,7 @@
 alpha/cvs-unwind-backtrace.diff
 
 amd64/submitted-rwlock-stack-imbalance.diff
-amd64/local-blacklist-on-TSX-Haswell.diff
+amd64/local-blacklist-for-Intel-TSX.diff
 amd64/cvs-slow-sse42.diff
 
 arm/local-ioperm.diff
@@ -272,3 +272,6 @@
 any/cvs-vfprintf.diff
 any/cvs-wscanf.diff
 any/cvs-ldconfig-aux-cache.diff
+any/cvs-ld_pointer_guard.diff
+any/cvs-mangle-tls_dtor_list.diff
+any/cvs-strxfrm-buffer-overflows.diff
Index: debian/changelog
===================================================================
--- debian/changelog	(révision 6511)
+++ debian/changelog	(copie de travail)
@@ -1,3 +1,31 @@
+glibc (2.19-18+deb8u2) stable; urgency=medium
+
+  [ Aurelien Jarno ]
+  * Update from upstream stable branch:
+    - Fix getaddrinfo sometimes returning uninitialized data with nscd.
+      Closes: #798515.
+    - Fix data corruption while reading the NSS files database
+      (CVE-2015-5277).  Closes: #799966.
+    - Fix buffer overflow (read past end of buffer) in internal_fnmatch.
+    - Fix  _IO_wstr_overflow integer overflow.
+    - Fix unexpected closing of nss_files databases after lookups, 
+      causing denial of service (CVE-2014-8121).  Closes: #779587.
+    - Fix NSCD netgroup cache.  Closes: #800523. 
+  * patches/any/cvs-ld_pointer_guard.diff: new patch from upstream to
+    unconditionally disable LD_POINTER_GUARD.  Closes: #798316, #801691.
+  * patches/any/cvs-mangle-tls_dtor_list.diff: new patch from upstream to
+    mangle function pointers in tls_dtor_list.  Closes: #802256.
+  * patches/any/cvs-strxfrm-buffer-overflows.diff: new patch from upstream
+    to fix memory allocations issues that can lead to buffer overflows on
+    the stack.  Closes: #803927.
+
+  [ Henrique de Moraes Holschuh ]
+  * Replace patches/amd64/local-blacklist-on-TSX-Haswell.diff by 
+    local-blacklist-for-Intel-TSX.diff also blacklisting some Broadwell
+    models.  Closes: #800574.
+
+ -- Aurelien Jarno <aurel32@debian.org>  Sun, 20 Dec 2015 23:20:45 +0100
+
 glibc (2.19-18+deb8u1) stable; urgency=medium
 
   [ Aurelien Jarno ]


-- System Information:
Debian Release: stretch/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.2.0-1-amd64 (SMP w/8 CPU cores)
Locale: LANG=fr_FR.utf8, LC_CTYPE=fr_FR.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)


Reply to: