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

eglibc packages for test



Hi,

I've backported the upstream patches to fix four CVEs in eglibc. For the
moment I've prepared the package for squeeze (debdiff attached), but I'm
on the way to create a package for wheezy too. Comments are more than
welcome, and the squeeze test package is available at:

    deb https://people.debian.org/~santiago/debian santiago-squeeze-lts/
    deb-src https://people.debian.org/~santiago/debian santiago-squeeze-lts/

Cheers,

Santiago
diff -u eglibc-2.11.3/debian/changelog eglibc-2.11.3/debian/changelog
--- eglibc-2.11.3/debian/changelog
+++ eglibc-2.11.3/debian/changelog
@@ -1,3 +1,17 @@
+eglibc (2.11.3-4+deb6u9~1) santiago-squeeze-lts; urgency=medium
+
+  * Non-maintainer upload by the Squeeze LTS Team.
+  * Fix CVE-2014-9761: Unbounded stack allocation in nan* functions.
+    Closes: #813187.
+  * Fix CVE-2015-8776: Segmentation fault caused by passing out-of-range data
+    to strftime(). Closes: #812445.
+  * Fix CVE-2015-8778: Integer overflow in hcreate and hcreate_r.
+    Closes: #812441.
+  * Fix CVE-2015-8779: Multiple unbounded stack allocations in catopen().
+    Closes: #812455.
+
+ -- Santiago Ruano Rincón <santiagorr@riseup.net>  Mon, 01 Feb 2016 21:48:58 +0100
+
 eglibc (2.11.3-4+deb6u8) squeeze-lts; urgency=medium
 
   * Non-maintainer upload by the Debian LTS team.
diff -u eglibc-2.11.3/debian/patches/series eglibc-2.11.3/debian/patches/series
--- eglibc-2.11.3/debian/patches/series
+++ eglibc-2.11.3/debian/patches/series
@@ -313,0 +314,7 @@
+any/cvs-CVE-2014-9761-1-squeeze.patch
+any/cvs-CVE-2014-9761-2-squeeze.patch
+any/cvs-CVE-2015-8776-squeeze.patch
+any/cvs-CVE-2015-8778-1-squeeze.patch
+any/cvs-CVE-2015-8778-2-squeeze.patch
+any/cvs-CVE-2015-8779-1-squeeze.patch
+any/cvs-CVE-2015-8779-2-squeeze.patch
only in patch2:
unchanged:
--- eglibc-2.11.3.orig/debian/patches/any/cvs-CVE-2014-9761-1-squeeze.patch
+++ eglibc-2.11.3/debian/patches/any/cvs-CVE-2014-9761-1-squeeze.patch
@@ -0,0 +1,982 @@
+From f481835906ce109333c84e491d49bab286a884e1 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Tue, 24 Nov 2015 22:24:52 +0000
+Subject: [PATCH] Refactor strtod parsing of NaN payloads.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The nan* functions handle their string argument by constructing a
+NAN(...) string on the stack as a VLA and passing it to strtod
+functions.
+
+This approach has problems discussed in bug 16961 and bug 16962: the
+stack usage is unbounded, and it gives incorrect results in certain
+cases where the argument is not a valid n-char-sequence.
+
+The natural fix for both issues is to refactor the NaN payload parsing
+out of strtod into a separate function that the nan* functions can
+call directly, so that no temporary string needs constructing on the
+stack at all.  This patch does that refactoring in preparation for
+fixing those bugs (but without actually using the new functions from
+nan* - which will also require exporting them from libc at version
+GLIBC_PRIVATE).  This patch is not intended to change any user-visible
+behavior, so no tests are added (fixes for the above bugs will of
+course add tests for them).
+
+This patch builds on my recent fixes for strtol and strtod issues in
+Turkish locales.  Given those fixes, the parsing of NaN payloads is
+locale-independent; thus, the new functions do not need to take a
+locale_t argument.
+
+Tested for x86_64, x86, mips64 and powerpc.
+
+	* 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 <ieee754.h>.
+	(____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.
+
+Signed-off-by: Santiago Ruano Rincón <santiagorr@riseup.net>
+---
+ include/stdlib.h                                 | 18 +++++++
+ include/wchar.h                                  |  3 ++
+ stdlib/Makefile                                  |  1 +
+ stdlib/strtod_l.c                                | 48 ++++--------------
+ stdlib/strtod_nan.c                              | 24 +++++++++
+ stdlib/strtod_nan_double.h                       | 30 +++++++++++
+ stdlib/strtod_nan_float.h                        | 29 +++++++++++
+ stdlib/strtod_nan_main.c                         | 63 ++++++++++++++++++++++++
+ stdlib/strtod_nan_narrow.h                       | 22 +++++++++
+ stdlib/strtod_nan_wide.h                         | 22 +++++++++
+ stdlib/strtof_l.c                                | 12 +----
+ stdlib/strtof_nan.c                              | 24 +++++++++
+ stdlib/strtold_nan.c                             | 30 +++++++++++
+ sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h    | 33 +++++++++++++
+ sysdeps/ieee754/ldbl-128/strtold_l.c             | 11 +----
+ sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h | 30 +++++++++++
+ sysdeps/ieee754/ldbl-128ibm/strtold_l.c          | 11 +----
+ sysdeps/ieee754/ldbl-64-128/strtold_l.c          | 11 +----
+ sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h     | 30 +++++++++++
+ sysdeps/ieee754/ldbl-96/strtold_l.c              | 11 +----
+ wcsmbs/Makefile                                  |  1 +
+ wcsmbs/wcstod_l.c                                |  3 --
+ wcsmbs/wcstod_nan.c                              | 23 +++++++++
+ wcsmbs/wcstof_l.c                                |  3 --
+ wcsmbs/wcstof_nan.c                              | 23 +++++++++
+ wcsmbs/wcstold_l.c                               |  3 --
+ wcsmbs/wcstold_nan.c                             | 30 +++++++++++
+ 27 files changed, 455 insertions(+), 94 deletions(-)
+ create mode 100644 stdlib/strtod_nan.c
+ create mode 100644 stdlib/strtod_nan_double.h
+ create mode 100644 stdlib/strtod_nan_float.h
+ create mode 100644 stdlib/strtod_nan_main.c
+ create mode 100644 stdlib/strtod_nan_narrow.h
+ create mode 100644 stdlib/strtod_nan_wide.h
+ create mode 100644 stdlib/strtof_nan.c
+ create mode 100644 stdlib/strtold_nan.c
+ create mode 100644 sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
+ create mode 100644 sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
+ create mode 100644 sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
+ create mode 100644 wcsmbs/wcstod_nan.c
+ create mode 100644 wcsmbs/wcstof_nan.c
+ create mode 100644 wcsmbs/wcstold_nan.c
+
+diff --git a/include/stdlib.h b/include/stdlib.h
+index d90e6ff..5c0c89a 100644
+--- a/include/stdlib.h
++++ b/include/stdlib.h
+@@ -186,6 +186,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,
+diff --git a/include/wchar.h b/include/wchar.h
+index bca8477..d62427d 100644
+--- a/include/wchar.h
++++ b/include/wchar.h
+@@ -51,6 +51,9 @@ extern unsigned long long int __wcstoull_internal (__const wchar_t *
+ 						   __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)
+diff --git a/stdlib/Makefile b/stdlib/Makefile
+index bf4df64..fd00e27 100644
+--- a/stdlib/Makefile
++++ b/stdlib/Makefile
+@@ -49,6 +49,7 @@ routines-y	:=							      \
+ 	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							      \
+ 	getsubopt xpg_basename						      \
+diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
+index fb40ad6..4c967ca 100644
+--- a/stdlib/strtod_l.c
++++ b/stdlib/strtod_l.c
+@@ -23,8 +23,6 @@
+ #include <xlocale.h>
+ 
+ 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
+@@ -36,21 +34,14 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
+ # 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);							      \
+-       if ((mant & 0xfffffffffffffULL) == 0)				      \
+-	 mant = 0x8000000000000ULL;					      \
+-       u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff;			      \
+-       u.ieee.mantissa1 = (mant) & 0xffffffff;				      \
+-       (flt) = u.d;							      \
+-  } while (0)
+ #endif
+ /* End of configuration part.  */
+ 
+@@ -106,7 +97,6 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
+ # 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
+@@ -118,7 +108,6 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
+ # 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
+ 
+ 
+@@ -585,33 +574,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
+ 	  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)
+diff --git a/stdlib/strtod_nan.c b/stdlib/strtod_nan.c
+new file mode 100644
+index 0000000..2a0a89f
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <strtod_nan_narrow.h>
++#include <strtod_nan_double.h>
++
++#define STRTOD_NAN __strtod_nan
++#include <strtod_nan_main.c>
+diff --git a/stdlib/strtod_nan_double.h b/stdlib/strtod_nan_double.h
+new file mode 100644
+index 0000000..f5bdb03
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#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)
+diff --git a/stdlib/strtod_nan_float.h b/stdlib/strtod_nan_float.h
+new file mode 100644
+index 0000000..4c52de8
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#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)
+diff --git a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c
+new file mode 100644
+index 0000000..bc37a63
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <ieee754.h>
++#include <locale.h>
++#include <math.h>
++#include <stdlib.h>
++#include <wchar.h>
++
++
++/* 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)
+diff --git a/stdlib/strtod_nan_narrow.h b/stdlib/strtod_nan_narrow.h
+new file mode 100644
+index 0000000..bd77045
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#define STRING_TYPE char
++#define L_(Ch) Ch
++#define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0,	\
++						   _nl_C_locobj_ptr)
+diff --git a/stdlib/strtod_nan_wide.h b/stdlib/strtod_nan_wide.h
+new file mode 100644
+index 0000000..783fbf4
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#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)
+diff --git a/stdlib/strtof_l.c b/stdlib/strtof_l.c
+index bbc7611..7bf20f1 100644
+--- a/stdlib/strtof_l.c
++++ b/stdlib/strtof_l.c
+@@ -21,27 +21,19 @@
+ #include <xlocale.h>
+ 
+ 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);							      \
+-       if ((mant & 0x7fffff) == 0)					      \
+-	 mant = 0x400000;						      \
+-       u.ieee.mantissa = (mant) & 0x7fffff;				      \
+-       (flt) = u.f;							      \
+-  } while (0)
+ 
+ #include "strtod_l.c"
+diff --git a/stdlib/strtof_nan.c b/stdlib/strtof_nan.c
+new file mode 100644
+index 0000000..b971310
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <strtod_nan_narrow.h>
++#include <strtod_nan_float.h>
++
++#define STRTOD_NAN __strtof_nan
++#include <strtod_nan_main.c>
+diff --git a/stdlib/strtold_nan.c b/stdlib/strtold_nan.c
+new file mode 100644
+index 0000000..dd43032
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <math.h>
++
++/* This function is unused if long double and double have the same
++   representation.  */
++#ifndef __NO_LONG_DOUBLE_MATH
++# include <strtod_nan_narrow.h>
++# include <strtod_nan_ldouble.h>
++
++# define STRTOD_NAN __strtold_nan
++# include <strtod_nan_main.c>
++#endif
+diff --git a/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
+new file mode 100644
+index 0000000..e0da4e2
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#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)
+diff --git a/sysdeps/ieee754/ldbl-128/strtold_l.c b/sysdeps/ieee754/ldbl-128/strtold_l.c
+index eb227fc..61ae6d4 100644
+--- a/sysdeps/ieee754/ldbl-128/strtold_l.c
++++ b/sysdeps/ieee754/ldbl-128/strtold_l.c
+@@ -26,20 +26,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.mantissa0 = 0x8000;					      \
+-       u.ieee.mantissa1 = 0;						      \
+-       u.ieee.mantissa2 = ((mant) >> 32);	      			      \
+-       u.ieee.mantissa3 = (mant) & 0xffffffff;				      \
+-       (flt) = u.d;							      \
+-  } while (0)
+ 
+ #include <strtod_l.c>
+diff --git a/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
+new file mode 100644
+index 0000000..876a4bb
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#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)
+diff --git a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
+index 4345039..6bb53c9 100644
+--- a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
++++ b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
+@@ -31,26 +31,19 @@ extern long double ____new_wcstold_l (const wchar_t *, wchar_t **, __locale_t);
+ # 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.d = (flt);							      \
+-       if ((mant & 0xfffffffffffffULL) == 0)				      \
+-	 mant = 0x8000000000000ULL;					      \
+-       u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff;			      \
+-       u.ieee.mantissa1 = (mant) & 0xffffffff;				      \
+-       (flt) = u.d;							      \
+-  } while (0)
+ 
+ #include <strtod_l.c>
+ 
+diff --git a/sysdeps/ieee754/ldbl-64-128/strtold_l.c b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
+index cdc3098..1e474d7 100644
+--- a/sysdeps/ieee754/ldbl-64-128/strtold_l.c
++++ b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
+@@ -31,26 +31,19 @@ extern long double ____new_wcstold_l (const wchar_t *, wchar_t **, __locale_t);
+ # 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.mantissa0 = 0x8000;					      \
+-       u.ieee.mantissa1 = 0;						      \
+-       u.ieee.mantissa2 = ((mant) >> 32);	      			      \
+-       u.ieee.mantissa3 = (mant) & 0xffffffff;				      \
+-       (flt) = u.d;							      \
+-  } while (0)
+ 
+ #include <strtod_l.c>
+ 
+diff --git a/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
+new file mode 100644
+index 0000000..6f03359
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#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)
+diff --git a/sysdeps/ieee754/ldbl-96/strtold_l.c b/sysdeps/ieee754/ldbl-96/strtold_l.c
+index 52335c2..fd09052 100644
+--- a/sysdeps/ieee754/ldbl-96/strtold_l.c
++++ b/sysdeps/ieee754/ldbl-96/strtold_l.c
+@@ -26,20 +26,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);							      \
+-       if ((mant & 0x7fffffffffffffffULL) == 0)				      \
+-	 mant = 0x4000000000000000ULL;					      \
+-       u.ieee.mantissa0 = (((mant) >> 32) & 0x7fffffff) | 0x80000000;	      \
+-       u.ieee.mantissa1 = (mant) & 0xffffffff;				      \
+-       (flt) = u.d;							      \
+-  } while (0)
+ 
+ #include <stdlib/strtod_l.c>
+diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
+index 3af3446..955d75f 100644
+--- a/wcsmbs/Makefile
++++ b/wcsmbs/Makefile
+@@ -40,6 +40,7 @@ routines-$(OPTION_POSIX_C_LANG_WIDE_CHAR) \
+ 	    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 \
+diff --git a/wcsmbs/wcstod_l.c b/wcsmbs/wcstod_l.c
+index 86ec18e..58ced14 100644
+--- a/wcsmbs/wcstod_l.c
++++ b/wcsmbs/wcstod_l.c
+@@ -24,9 +24,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
+ 
+diff --git a/wcsmbs/wcstod_nan.c b/wcsmbs/wcstod_nan.c
+new file mode 100644
+index 0000000..b3dd6af
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#include "../stdlib/strtod_nan_wide.h"
++#include "../stdlib/strtod_nan_double.h"
++
++#define STRTOD_NAN __wcstod_nan
++#include "../stdlib/strtod_nan_main.c"
+diff --git a/wcsmbs/wcstof_l.c b/wcsmbs/wcstof_l.c
+index 0ed31e0..89311c0 100644
+--- a/wcsmbs/wcstof_l.c
++++ b/wcsmbs/wcstof_l.c
+@@ -26,8 +26,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 <stdlib/strtof_l.c>
+diff --git a/wcsmbs/wcstof_nan.c b/wcsmbs/wcstof_nan.c
+new file mode 100644
+index 0000000..c5f667a
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#include "../stdlib/strtod_nan_wide.h"
++#include "../stdlib/strtod_nan_float.h"
++
++#define STRTOD_NAN __wcstof_nan
++#include "../stdlib/strtod_nan_main.c"
+diff --git a/wcsmbs/wcstold_l.c b/wcsmbs/wcstold_l.c
+index 9526645..83954f6 100644
+--- a/wcsmbs/wcstold_l.c
++++ b/wcsmbs/wcstold_l.c
+@@ -25,8 +25,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 <strtold_l.c>
+diff --git a/wcsmbs/wcstold_nan.c b/wcsmbs/wcstold_nan.c
+new file mode 100644
+index 0000000..ef905d3
+--- /dev/null
++++ b/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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <math.h>
++
++/* 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 <strtod_nan_ldouble.h>
++
++# define STRTOD_NAN __wcstold_nan
++# include "../stdlib/strtod_nan_main.c"
++#endif
+-- 
+2.6.4
+
only in patch2:
unchanged:
--- eglibc-2.11.3.orig/debian/patches/any/cvs-CVE-2014-9761-2-squeeze.patch
+++ eglibc-2.11.3/debian/patches/any/cvs-CVE-2014-9761-2-squeeze.patch
@@ -0,0 +1,339 @@
+From 3a84cf40c8d429cafa7b42179792b7cd190c4efa Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Fri, 4 Dec 2015 20:36:28 +0000
+Subject: [PATCH] Fix nan functions handling of payload strings (bug 16961, bug
+ 16962).
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The nan, nanf and nanl functions handle payload strings by doing e.g.:
+
+  if (tagp[0] != '\0')
+    {
+      char buf[6 + strlen (tagp)];
+      sprintf (buf, "NAN(%s)", tagp);
+      return strtod (buf, NULL);
+    }
+
+This is an unbounded stack allocation based on the length of the
+argument.  Furthermore, if the argument starts with an n-char-sequence
+followed by ')', that n-char-sequence is wrongly treated as
+significant for determining the payload of the resulting NaN, when ISO
+C says the call should be equivalent to strtod ("NAN", NULL), without
+being affected by that initial n-char-sequence.  This patch fixes both
+those problems by using the __strtod_nan etc. functions recently
+factored out of strtod etc. for that purpose, with those functions
+being exported from libc at version GLIBC_PRIVATE.
+
+Tested for x86_64, x86, mips64 and powerpc.
+
+	[BZ #16961]
+	[BZ #16962]
+	* math/s_nan.c (__nan): Use __strtod_nan instead of constructing a
+	string on the stack for strtod.
+	* math/s_nanf.c (__nanf): Use __strtof_nan instead of constructing
+	a string on the stack for strtof.
+	* math/s_nanl.c (__nanl): Use __strtold_nan instead of
+	constructing a string on the stack for strtold.
+	* stdlib/Versions (libc): Add __strtof_nan, __strtod_nan and
+	__strtold_nan to GLIBC_PRIVATE.
+	* math/test-nan-overflow.c: New file.
+	* math/test-nan-payload.c: Likewise.
+	* math/Makefile (tests): Add test-nan-overflow and
+	test-nan-payload.
+
+Signed-off-by: Santiago Ruano Rincón <santiagorr@riseup.net>
+---
+ math/Makefile            |   3 +-
+ math/s_nan.c             |   9 +---
+ math/s_nanf.c            |   9 +---
+ math/s_nanl.c            |   9 +---
+ math/test-nan-overflow.c |  66 +++++++++++++++++++++++++
+ math/test-nan-payload.c  | 122 +++++++++++++++++++++++++++++++++++++++++++++++
+ stdlib/Versions          |   1 +
+ 7 files changed, 194 insertions(+), 25 deletions(-)
+ create mode 100644 math/test-nan-overflow.c
+ create mode 100644 math/test-nan-payload.c
+
+Index: eglibc-2.11.3/math/Makefile
+===================================================================
+--- eglibc-2.11.3.orig/math/Makefile
++++ eglibc-2.11.3/math/Makefile
+@@ -93,7 +93,7 @@ distribute += $(filter-out $(generated),
+ tests = test-matherr test-fenv atest-exp atest-sincos atest-exp2 basic-test \
+ 	test-misc test-fpucw tst-definitions test-tgmath test-tgmath-ret \
+ 	bug-nextafter bug-nexttoward bug-tgmath1 test-tgmath-int \
+-	test-powl
++	test-powl test-nan-overflow test-nan-payload
+ # We do the `long double' tests only if this data type is available.
+ test-longdouble-yes = test-ldouble test-ildoubl
+ distribute += $(test-longdouble-yes:=.c)
+Index: eglibc-2.11.3/math/s_nan.c
+===================================================================
+--- eglibc-2.11.3.orig/math/s_nan.c
++++ eglibc-2.11.3/math/s_nan.c
+@@ -28,14 +28,7 @@
+ double
+ __nan (const char *tagp)
+ {
+-  if (tagp[0] != '\0')
+-    {
+-      char buf[6 + strlen (tagp)];
+-      sprintf (buf, "NAN(%s)", tagp);
+-      return strtod (buf, NULL);
+-    }
+-
+-  return NAN;
++  return __strtod_nan (tagp, NULL, 0);
+ }
+ weak_alias (__nan, nan)
+ #ifdef NO_LONG_DOUBLE
+Index: eglibc-2.11.3/math/s_nanf.c
+===================================================================
+--- eglibc-2.11.3.orig/math/s_nanf.c
++++ eglibc-2.11.3/math/s_nanf.c
+@@ -28,13 +28,6 @@
+ float
+ __nanf (const char *tagp)
+ {
+-  if (tagp[0] != '\0')
+-    {
+-      char buf[6 + strlen (tagp)];
+-      sprintf (buf, "NAN(%s)", tagp);
+-      return strtof (buf, NULL);
+-    }
+-
+-  return NAN;
++  return __strtof_nan (tagp, NULL, 0);
+ }
+ weak_alias (__nanf, nanf)
+Index: eglibc-2.11.3/math/s_nanl.c
+===================================================================
+--- eglibc-2.11.3.orig/math/s_nanl.c
++++ eglibc-2.11.3/math/s_nanl.c
+@@ -28,13 +28,6 @@
+ long double
+ __nanl (const char *tagp)
+ {
+-  if (tagp[0] != '\0')
+-    {
+-      char buf[6 + strlen (tagp)];
+-      sprintf (buf, "NAN(%s)", tagp);
+-      return strtold (buf, NULL);
+-    }
+-
+-  return NAN;
++  return __strtold_nan (tagp, NULL, 0);
+ }
+ weak_alias (__nanl, nanl)
+Index: eglibc-2.11.3/math/test-nan-overflow.c
+===================================================================
+--- /dev/null
++++ eglibc-2.11.3/math/test-nan-overflow.c
+@@ -0,0 +1,66 @@
++/* Test nan functions stack overflow (bug 16962).
++   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 <math.h>
++#include <stdio.h>
++#include <string.h>
++#include <sys/resource.h>
++
++#define STACK_LIM 1048576
++#define STRING_SIZE (2 * STACK_LIM)
++
++static int
++do_test (void)
++{
++  int result = 0;
++  struct rlimit lim;
++  getrlimit (RLIMIT_STACK, &lim);
++  lim.rlim_cur = STACK_LIM;
++  setrlimit (RLIMIT_STACK, &lim);
++  char *nanstr = malloc (STRING_SIZE);
++  if (nanstr == NULL)
++    {
++      puts ("malloc failed, cannot test");
++      return 77;
++    }
++  memset (nanstr, '0', STRING_SIZE - 1);
++  nanstr[STRING_SIZE - 1] = 0;
++#define NAN_TEST(TYPE, FUNC)			\
++  do						\
++    {						\
++      char *volatile p = nanstr;		\
++      volatile TYPE v = FUNC (p);		\
++      if (isnan (v))				\
++	puts ("PASS: " #FUNC);			\
++      else					\
++	{					\
++	  puts ("FAIL: " #FUNC);		\
++	  result = 1;				\
++	}					\
++    }						\
++  while (0)
++  NAN_TEST (float, nanf);
++  NAN_TEST (double, nan);
++#ifndef NO_LONG_DOUBLE
++  NAN_TEST (long double, nanl);
++#endif
++  return result;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+Index: eglibc-2.11.3/math/test-nan-payload.c
+===================================================================
+--- /dev/null
++++ eglibc-2.11.3/math/test-nan-payload.c
+@@ -0,0 +1,122 @@
++/* Test nan functions payload handling (bug 16961).
++   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 <float.h>
++#include <math.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++/* Avoid built-in functions.  */
++#define WRAP_NAN(FUNC, STR) \
++  ({ const char *volatile wns = (STR); FUNC (wns); })
++#define WRAP_STRTO(FUNC, STR) \
++  ({ const char *volatile wss = (STR); FUNC (wss, NULL); })
++
++#define CHECK_IS_NAN(TYPE, A)			\
++  do						\
++    {						\
++      if (isnan (A))				\
++	puts ("PASS: " #TYPE " " #A);		\
++      else					\
++	{					\
++	  puts ("FAIL: " #TYPE " " #A);		\
++	  result = 1;				\
++	}					\
++    }						\
++  while (0)
++
++#define CHECK_SAME_NAN(TYPE, A, B)			\
++  do							\
++    {							\
++      if (memcmp (&(A), &(B), sizeof (A)) == 0)		\
++	puts ("PASS: " #TYPE " " #A " = " #B);		\
++      else						\
++	{						\
++	  puts ("FAIL: " #TYPE " " #A " = " #B);	\
++	  result = 1;					\
++	}						\
++    }							\
++  while (0)
++
++#define CHECK_DIFF_NAN(TYPE, A, B)			\
++  do							\
++    {							\
++      if (memcmp (&(A), &(B), sizeof (A)) != 0)		\
++	puts ("PASS: " #TYPE " " #A " != " #B);		\
++      else						\
++	{						\
++	  puts ("FAIL: " #TYPE " " #A " != " #B);	\
++	  result = 1;					\
++	}						\
++    }							\
++  while (0)
++
++/* Cannot test payloads by memcmp for formats where NaNs have padding
++   bits.  */
++#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106)
++
++#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG)		\
++  do							\
++    {							\
++     TYPE n123 = WRAP_NAN (FUNC, "123");		\
++     CHECK_IS_NAN (TYPE, n123);				\
++     TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)");	\
++     CHECK_IS_NAN (TYPE, s123);				\
++     TYPE n456 = WRAP_NAN (FUNC, "456");		\
++     CHECK_IS_NAN (TYPE, n456);				\
++     TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)");	\
++     CHECK_IS_NAN (TYPE, s456);				\
++     TYPE n123x = WRAP_NAN (FUNC, "123)");		\
++     CHECK_IS_NAN (TYPE, n123x);			\
++     TYPE nemp = WRAP_NAN (FUNC, "");			\
++     CHECK_IS_NAN (TYPE, nemp);				\
++     TYPE semp = WRAP_STRTO (SFUNC, "NAN()");		\
++     CHECK_IS_NAN (TYPE, semp);				\
++     TYPE sx = WRAP_STRTO (SFUNC, "NAN");		\
++     CHECK_IS_NAN (TYPE, sx);				\
++     if (CAN_TEST_EQ (MANT_DIG))			\
++       CHECK_SAME_NAN (TYPE, n123, s123);		\
++     if (CAN_TEST_EQ (MANT_DIG))			\
++       CHECK_SAME_NAN (TYPE, n456, s456);		\
++     if (CAN_TEST_EQ (MANT_DIG))			\
++       CHECK_SAME_NAN (TYPE, nemp, semp);		\
++     if (CAN_TEST_EQ (MANT_DIG))			\
++       CHECK_SAME_NAN (TYPE, n123x, sx);		\
++     CHECK_DIFF_NAN (TYPE, n123, n456);			\
++     CHECK_DIFF_NAN (TYPE, n123, nemp);			\
++     CHECK_DIFF_NAN (TYPE, n123, n123x);		\
++     CHECK_DIFF_NAN (TYPE, n456, nemp);			\
++     CHECK_DIFF_NAN (TYPE, n456, n123x);		\
++    }							\
++  while (0)
++
++static int
++do_test (void)
++{
++  int result = 0;
++  RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG);
++  RUN_TESTS (double, strtod, nan, DBL_MANT_DIG);
++#ifndef NO_LONG_DOUBLE
++  RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG);
++#endif
++  return result;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+Index: eglibc-2.11.3/stdlib/Versions
+===================================================================
+--- eglibc-2.11.3.orig/stdlib/Versions
++++ eglibc-2.11.3/stdlib/Versions
+@@ -8,6 +8,7 @@ libc {
+ 
+     # functions used in other libraries
+     __secure_getenv;
++    __strtof_nan; __strtod_nan; __strtold_nan;
+ 
+     # a*
+     a64l; abort; abs; atexit; atof; atoi; atol; atoll;
only in patch2:
unchanged:
--- eglibc-2.11.3.orig/debian/patches/any/cvs-CVE-2015-8776-squeeze.patch
+++ eglibc-2.11.3/debian/patches/any/cvs-CVE-2015-8776-squeeze.patch
@@ -0,0 +1,136 @@
+From 42b1d94e816d82cd5f4d386baef512c5c21e9910 Mon Sep 17 00:00:00 2001
+From: Paul Pluzhnikov <ppluzhnikov@google.com>
+Date: Sat, 26 Sep 2015 13:27:48 -0700
+Subject: [PATCH] Fix BZ #18985 -- out of range data to strftime() causes a
+ segfault
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Santiago Ruano Rincón <santiagorr@riseup.net>
+---
+ time/strftime_l.c   | 20 +++++++++++++-------
+ time/tst-strftime.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 64 insertions(+), 8 deletions(-)
+
+diff --git a/time/strftime_l.c b/time/strftime_l.c
+index fcc57d5..34e7481 100644
+--- a/time/strftime_l.c
++++ b/time/strftime_l.c
+@@ -518,13 +518,17 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
+      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)))
+@@ -534,8 +538,10 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
+ # 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))
+@@ -1329,7 +1335,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
+ 		  *tzset_called = true;
+ 		}
+ # endif
+-	      zone = tzname[tp->tm_isdst];
++	      zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?";
+ 	    }
+ #endif
+ 	  if (! zone)
+diff --git a/time/tst-strftime.c b/time/tst-strftime.c
+index 374fba4..af3ff72 100644
+--- a/time/tst-strftime.c
++++ b/time/tst-strftime.c
+@@ -4,6 +4,56 @@
+ #include <time.h>
+ 
+ 
++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 ()
+-- 
+2.6.4
+
only in patch2:
unchanged:
--- eglibc-2.11.3.orig/debian/patches/any/cvs-CVE-2015-8778-1-squeeze.patch
+++ eglibc-2.11.3/debian/patches/any/cvs-CVE-2015-8778-1-squeeze.patch
@@ -0,0 +1,52 @@
+From a94f8da796018986cd9f2a20d4c797d0f5e525ea Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20B=C3=ADlka?= <neleai@seznam.cz>
+Date: Sat, 11 Jul 2015 17:44:10 +0200
+Subject: [PATCH] Handle overflow in __hcreate_r
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Hi,
+
+As in bugzilla entry there is overflow in hsearch when looking for prime
+number as SIZE_MAX - 1 is divisible by 5. We fix that by rejecting large
+inputs before looking for prime.
+
+	* misc/hsearch_r.c (__hcreate_r): Handle overflow.
+
+(cherry picked from commit 2f5c1750558fe64bac361f52d6827ab1bcfe52bc)
+Signed-off-by: Santiago Ruano Rincón <santiagorr@riseup.net>
+---
+ misc/hsearch_r.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/misc/hsearch_r.c b/misc/hsearch_r.c
+index 73b9565..93d4d03 100644
+--- a/misc/hsearch_r.c
++++ b/misc/hsearch_r.c
+@@ -21,7 +21,7 @@
+ #include <errno.h>
+ #include <malloc.h>
+ #include <string.h>
+-
++#include <stdint.h>
+ #include <search.h>
+ 
+ /* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
+@@ -75,6 +75,13 @@ hcreate_r (nel, htab)
+       return 0;
+     }
+ 
++  if (nel >= SIZE_MAX / sizeof (_ENTRY))
++    {
++      __set_errno (ENOMEM);
++      return 0;
++    }
++
++
+   /* There is still another table active. Return with error. */
+   if (htab->table != NULL)
+     return 0;
+-- 
+2.6.4
+
only in patch2:
unchanged:
--- eglibc-2.11.3.orig/debian/patches/any/cvs-CVE-2015-8778-2-squeeze.patch
+++ eglibc-2.11.3/debian/patches/any/cvs-CVE-2015-8778-2-squeeze.patch
@@ -0,0 +1,177 @@
+From 7f9735837ee01f5c3f1124a3fda1fc402bc07fb8 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 28 Jan 2016 13:59:11 +0100
+Subject: [PATCH] Improve check against integer wraparound in hcreate_r [BZ
+ #18240]
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+(cherry picked from commit bae7c7c764413b23e61cb099ce33be4c4ee259bb)
+Signed-off-by: Santiago Ruano Rincón <santiagorr@riseup.net>
+---
+ misc/Makefile    |  2 +-
+ misc/bug18240.c  | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ misc/hsearch_r.c | 35 +++++++++++++-------------
+ 3 files changed, 93 insertions(+), 19 deletions(-)
+ create mode 100644 misc/bug18240.c
+
+diff --git a/misc/Makefile b/misc/Makefile
+index 65dd1aa..447976d 100644
+--- a/misc/Makefile
++++ b/misc/Makefile
+@@ -86,7 +86,7 @@ endif
+ gpl2lgpl := error.c error.h
+ 
+ tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
+-	 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
++	 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 bug18240
+ tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) += tst-error1
+ tests-$(OPTION_EGLIBC_FCVT) += tst-efgcvt
+ # eglibc: ifeq (no,$(cross-compiling))
+diff --git a/misc/bug18240.c b/misc/bug18240.c
+new file mode 100644
+index 0000000..4b26865
+--- /dev/null
++++ b/misc/bug18240.c
+@@ -0,0 +1,75 @@
++/* 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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <errno.h>
++#include <limits.h>
++#include <search.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++
++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)
++{
++  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"
+diff --git a/misc/hsearch_r.c b/misc/hsearch_r.c
+index 93d4d03..c5108c2 100644
+--- a/misc/hsearch_r.c
++++ b/misc/hsearch_r.c
+@@ -48,15 +48,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
+@@ -75,13 +72,6 @@ hcreate_r (nel, htab)
+       return 0;
+     }
+ 
+-  if (nel >= SIZE_MAX / sizeof (_ENTRY))
+-    {
+-      __set_errno (ENOMEM);
+-      return 0;
+-    }
+-
+-
+   /* There is still another table active. Return with error. */
+   if (htab->table != NULL)
+     return 0;
+@@ -90,10 +80,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;
+-- 
+2.6.4
+
only in patch2:
unchanged:
--- eglibc-2.11.3.orig/debian/patches/any/cvs-CVE-2015-8779-1-squeeze.patch
+++ eglibc-2.11.3/debian/patches/any/cvs-CVE-2015-8779-1-squeeze.patch
@@ -0,0 +1,229 @@
+From 64e9f2f3c5c8bc3bb6df2a34a85827715dcebf83 Mon Sep 17 00:00:00 2001
+From: Paul Pluzhnikov <ppluzhnikov@google.com>
+Date: Sat, 8 Aug 2015 15:53:03 -0700
+Subject: [PATCH] Fix BZ #17905
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+(cherry picked from commit 0f58539030e436449f79189b6edab17d7479796e)
+Signed-off-by: Santiago Ruano Rincón <santiagorr@riseup.net>
+---
+ catgets/Makefile       | 11 ++++++++---
+ catgets/catgets.c      | 19 ++++++++++++-------
+ catgets/open_catalog.c | 23 ++++++++++++++---------
+ catgets/tst-catgets.c  | 31 +++++++++++++++++++++++++++++++
+ 4 files changed, 65 insertions(+), 19 deletions(-)
+
+diff --git a/catgets/Makefile b/catgets/Makefile
+index e419803..03061d2 100644
+--- a/catgets/Makefile
++++ b/catgets/Makefile
+@@ -50,15 +50,15 @@ catgets-CPPFLAGS := -DNLSPATH='"$(msgcatdir)/%L/%N:$(msgcatdir)/%L/LC_MESSAGES/%
+ CPPFLAGS-gencat = -DNOT_IN_libc
+ 
+ generated = de.msg test1.cat test1.h test2.cat test2.h sample.SJIS.cat \
+-	    test-gencat.h
++	    test-gencat.h 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
+ 
+ # eglibc: ifneq ($(cross-compiling),yes)
+ ifeq (y,$(OPTION_EGLIBC_CATGETS))
+ tests: $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
+-       $(objpfx)test-gencat.out
++       $(objpfx)test-gencat.out $(objpfx)tst-catgets-mem.out
+ endif
+ # This test just checks whether the program produces any error or not.
+ # The result is not tested.
+@@ -87,4 +87,9 @@ $(objpfx)test-gencat.out: test-gencat.sh $(objpfx)test-gencat \
+ $(objpfx)sample.SJIS.cat: sample.SJIS $(objpfx)gencat
+ 	GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
+ 	$(built-program-cmd) -H $(objpfx)test-gencat.h < $(word 1,$^) > $@
++
++$(objpfx)tst-catgets-mem.out: $(objpfx)tst-catgets.out
++	$(common-objpfx)malloc/mtrace $(objpfx)tst-catgets.mtrace > $@; \
++	$(evaluate-test)
++
+ # eglibc: endif
+diff --git a/catgets/catgets.c b/catgets/catgets.c
+index 9fd0115..640d507 100644
+--- a/catgets/catgets.c
++++ b/catgets/catgets.c
+@@ -17,7 +17,6 @@
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+ 
+-#include <alloca.h>
+ #include <errno.h>
+ #include <locale.h>
+ #include <nl_types.h>
+@@ -36,6 +35,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)
+     {
+@@ -55,7 +55,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 (__builtin_expect ((tmp == NULL), 0))
++	    return (nl_catd) -1;
+ 
+ 	  __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
+ 	  nlspath = tmp;
+@@ -66,16 +69,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;
+ }
+ 
+diff --git a/catgets/open_catalog.c b/catgets/open_catalog.c
+index 8c563b2..07f4052 100644
+--- a/catgets/open_catalog.c
++++ b/catgets/open_catalog.c
+@@ -48,6 +48,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
+   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);
+@@ -58,23 +59,23 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
+   if (__builtin_expect (bufact + (n) >= bufmax, 0))			      \
+     {									      \
+       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 (__builtin_expect ((buf == NULL), 0))				      \
++	{								      \
++	  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')
+ 	{
+@@ -189,7 +190,10 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
+ 
+   /* 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;
+@@ -326,6 +330,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
+   /* Release the lock again.  */
+  close_unlock_return:
+   close_not_cancel_no_status (fd);
++  free (buf);
+ 
+   return result;
+ }
+diff --git a/catgets/tst-catgets.c b/catgets/tst-catgets.c
+index fdaa834..3e1fe84 100644
+--- a/catgets/tst-catgets.c
++++ b/catgets/tst-catgets.c
+@@ -1,7 +1,10 @@
++#include <assert.h>
+ #include <mcheck.h>
+ #include <nl_types.h>
+ #include <stdio.h>
++#include <stdlib.h>
+ #include <string.h>
++#include <sys/resource.h>
+ 
+ 
+ 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
+ 
+ int
+@@ -62,5 +92,6 @@ main (void)
+ 	}
+     }
+ 
++  result += do_bz17905 ();
+   return result;
+ }
+-- 
+2.6.4
+
only in patch2:
unchanged:
--- eglibc-2.11.3.orig/debian/patches/any/cvs-CVE-2015-8779-2-squeeze.patch
+++ eglibc-2.11.3/debian/patches/any/cvs-CVE-2015-8779-2-squeeze.patch
@@ -0,0 +1,30 @@
+From 064969e7493a880bd9ede68cd2d8663723589107 Mon Sep 17 00:00:00 2001
+From: Paul Pluzhnikov <ppluzhnikov@google.com>
+Date: Sat, 8 Aug 2015 15:54:40 -0700
+Subject: [PATCH] Fix trailing space.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+(cherry picked from commit 7565d2a862683a3c26ffb1f32351b8c5ab9f7b31)
+Signed-off-by: Santiago Ruano Rincón <santiagorr@riseup.net>
+---
+ catgets/tst-catgets.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/catgets/tst-catgets.c b/catgets/tst-catgets.c
+index 3e1fe84..25ef056 100644
+--- a/catgets/tst-catgets.c
++++ b/catgets/tst-catgets.c
+@@ -30,7 +30,7 @@ do_bz17905 (void)
+   rl.rlim_cur = sz;
+   setrlimit (RLIMIT_STACK, &rl);
+ 
+-  buf = malloc (sz + 1); 
++  buf = malloc (sz + 1);
+   memset (buf, 'A', sz);
+   buf[sz] = '\0';
+   setenv ("NLSPATH", buf, 1);
+-- 
+2.6.4
+

Attachment: signature.asc
Description: PGP signature


Reply to: