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

[glibc] 01/01: Update from upstream stable branch



This is an automated email from the git hooks/post-receive script.

aurel32 pushed a commit to branch jessie
in repository glibc.

commit 9792f19af42e3760fffc61cd1d8391d259f89214
Author: Aurelien Jarno <aurelien@aurel32.net>
Date:   Wed Jan 27 18:47:18 2016 +0100

    Update from upstream stable branch
    
    - Fix segmentation fault caused by passing out-of-range data to strftime()
      (CVE-2015-8776).  Closes: #812445.
    - Fix multiple unbounded stack allocations in catopen() (CVE-2015-8779).
      Closes: #812455.
---
 debian/changelog                |  11 ++
 debian/patches/git-updates.diff | 352 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 358 insertions(+), 5 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 2a1f090..0931f1b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+glibc (2.19-18+deb8u3) UNRELEASED; urgency=medium
+
+  [ Aurelien Jarno ]
+  * Update from upstream stable branch:
+    - Fix segmentation fault caused by passing out-of-range data to strftime()
+      (CVE-2015-8776).  Closes: #812445.
+    - Fix multiple unbounded stack allocations in catopen() (CVE-2015-8779).
+      Closes: #812455.
+
+ -- Aurelien Jarno <aurel32@debian.org>  Wed, 27 Jan 2016 18:46:44 +0100
+
 glibc (2.19-18+deb8u2) stable; urgency=medium
 
   [ Aurelien Jarno ]
diff --git a/debian/patches/git-updates.diff b/debian/patches/git-updates.diff
index d994466..ceefe46 100644
--- a/debian/patches/git-updates.diff
+++ b/debian/patches/git-updates.diff
@@ -1,10 +1,26 @@
 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..e82ba7d 100644
+index 81c393a..871c722 100644
 --- a/ChangeLog
 +++ b/ChangeLog
-@@ -1,3 +1,406 @@
+@@ -1,3 +1,422 @@
++2015-09-26  Paul Pluzhnikov  <ppluzhnikov@google.com>
++
++	[BZ #18985]
++	* time/strftime_l.c (a_wkday, f_wkday, a_month, f_month): Range check.
++	(__strftime_internal): Likewise.
++	* time/tst-strftime.c (do_bz18985): New test.
++	(do_test): Call it.
++
++2015-08-08  Paul Pluzhnikov  <ppluzhnikov@google.com>
++
++	[BZ #17905]
++	* catgets/Makefile (tst-catgets-mem): New test.
++	* catgets/catgets.c (catopen): Don't use unbounded alloca.
++	* catgets/open_catalog.c (__open_catalog): Likewise.
++	* catgets/tst-catgets.c (do_bz17905): Test unbounded alloca.
++
 +2015-12-20  Siddhesh Poyarekar  <siddhesh@redhat.com>
 +
 +	[BZ #16758]
@@ -412,7 +428,7 @@ index 81c393a..e82ba7d 100644
  
  	[BZ #16529]
 diff --git a/NEWS b/NEWS
-index 98b479e..2972c4a 100644
+index 98b479e..44fe916 100644
 --- a/NEWS
 +++ b/NEWS
 @@ -5,6 +5,65 @@ See the end for copying conditions.
@@ -425,8 +441,8 @@ index 98b479e..2972c4a 100644
 +
 +  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.
++  17079, 17137, 17153, 17213, 17263, 17269, 17325, 17555, 17905, 18007,
++  18032, 18287, 18905.
 +
 +* A buffer overflow in gethostbyname_r and related functions performing DNS
 +  requests has been fixed.  If the NSS functions were called with a
@@ -481,6 +497,214 @@ index 98b479e..2972c4a 100644
  Version 2.19
  
  * The following bugs are resolved with this release:
+diff --git a/catgets/Makefile b/catgets/Makefile
+index c95442d..8c39e3d 100644
+--- a/catgets/Makefile
++++ b/catgets/Makefile
+@@ -45,14 +45,14 @@ 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
+ 
+ ifeq ($(run-built-tests),yes)
+ tests: $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
+-       $(objpfx)test-gencat.out
++       $(objpfx)test-gencat.out $(objpfx)tst-catgets-mem.out
+ # This test just checks whether the program produces any error or not.
+ # The result is not tested.
+ $(objpfx)test1.cat: test1.msg $(objpfx)gencat
+@@ -80,4 +80,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)
++
+ endif
+diff --git a/catgets/catgets.c b/catgets/catgets.c
+index eac2827..820c0f6 100644
+--- a/catgets/catgets.c
++++ b/catgets/catgets.c
+@@ -16,7 +16,6 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
+-#include <alloca.h>
+ #include <errno.h>
+ #include <locale.h>
+ #include <nl_types.h>
+@@ -35,6 +34,7 @@ catopen (const char *cat_name, int flag)
+   __nl_catd result;
+   const char *env_var = NULL;
+   const char *nlspath = NULL;
++  char *tmp = NULL;
+ 
+   if (strchr (cat_name, '/') == NULL)
+     {
+@@ -54,7 +54,10 @@ catopen (const char *cat_name, int flag)
+ 	{
+ 	  /* Append the system dependent directory.  */
+ 	  size_t len = strlen (nlspath) + 1 + sizeof NLSPATH;
+-	  char *tmp = alloca (len);
++	  tmp = malloc (len);
++
++	  if (__glibc_unlikely (tmp == NULL))
++	    return (nl_catd) -1;
+ 
+ 	  __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
+ 	  nlspath = tmp;
+@@ -65,16 +68,18 @@ catopen (const char *cat_name, int flag)
+ 
+   result = (__nl_catd) malloc (sizeof (*result));
+   if (result == NULL)
+-    /* We cannot get enough memory.  */
+-    return (nl_catd) -1;
+-
+-  if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
++    {
++      /* We cannot get enough memory.  */
++      result = (nl_catd) -1;
++    }
++  else if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
+     {
+       /* Couldn't open the file.  */
+       free ((void *) result);
+-      return (nl_catd) -1;
++      result = (nl_catd) -1;
+     }
+ 
++  free (tmp);
+   return (nl_catd) result;
+ }
+ 
+diff --git a/catgets/open_catalog.c b/catgets/open_catalog.c
+index bc44f98..5fa4011 100644
+--- a/catgets/open_catalog.c
++++ b/catgets/open_catalog.c
+@@ -47,6 +47,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);
+@@ -57,23 +58,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 (__glibc_unlikely (buf == NULL))				      \
++	{								      \
++	  free (old_buf);						      \
++	  return -1;							      \
++	}								      \
+     }
+ 
+       /* The RUN_NLSPATH variable contains a colon separated list of
+ 	 descriptions where we expect to find catalogs.  We have to
+ 	 recognize certain % substitutions and stop when we found the
+ 	 first existing file.  */
+-      char *buf;
+       size_t bufact;
+-      size_t bufmax;
++      size_t bufmax = 0;
+       size_t len;
+ 
+-      buf = NULL;
+-      bufmax = 0;
+-
+       fd = -1;
+       while (*run_nlspath != '\0')
+ 	{
+@@ -188,7 +189,10 @@ __open_catalog (const char *cat_name, 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;
+@@ -325,6 +329,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..25ef056 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;
+ }
 diff --git a/elf/Makefile b/elf/Makefile
 index 4c58fc9..b9da0b8 100644
 --- a/elf/Makefile
@@ -5775,6 +5999,124 @@ index 207b6c0..25c112f 100644
  ifloat: 1
  Test "yn (10, 0xcp-4)":
  double: 1
+diff --git a/time/strftime_l.c b/time/strftime_l.c
+index dfb7b4c..29c7cdd 100644
+--- a/time/strftime_l.c
++++ b/time/strftime_l.c
+@@ -509,13 +509,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)))
+@@ -525,8 +529,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))
+@@ -1320,7 +1326,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 ()
 diff --git a/timezone/Makefile b/timezone/Makefile
 index f5fb424..58e7f50 100644
 --- a/timezone/Makefile

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-glibc/glibc.git


Reply to: