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

[glibc] 03/03: patches/any/cvs-catopen.diff: new patch from upstream to fix multiple unbounded stack allocations in catopen() (CVE-2015-8779). Closes: #812455.



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

aurel32 pushed a commit to branch wheezy
in repository glibc.

commit 1dc30ec7d2262020c01af655e0e43d6be5030c93
Author: Aurelien Jarno <aurelien@aurel32.net>
Date:   Mon Feb 1 08:21:28 2016 +0100

    patches/any/cvs-catopen.diff: new patch from upstream to fix multiple unbounded stack allocations in catopen() (CVE-2015-8779).  Closes: #812455.
---
 debian/changelog                    |   3 +
 debian/patches/any/cvs-catopen.diff | 208 ++++++++++++++++++++++++++++++++++++
 debian/patches/series               |   1 +
 3 files changed, 212 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index a3ca112..62a7344 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,9 @@ eglibc (2.13-38+deb7u10) UNRELEASED; urgency=medium
     (CVE-2015-8776).  Closes: #812445.
   * patches/any/cvs-hcreate.diff: new patch from upstream to fix an integer
     overflow in hcreate() and hcreate_r() (CVE-2015-8778). Closes: #812441.
+  * patches/any/cvs-catopen.diff: new patch from upstream to fix multiple
+    unbounded stack allocations in catopen() (CVE-2015-8779).  Closes:
+    #812455.
 
  -- Aurelien Jarno <aurel32@debian.org>  Sun, 31 Jan 2016 12:55:29 +0100
 
diff --git a/debian/patches/any/cvs-catopen.diff b/debian/patches/any/cvs-catopen.diff
new file mode 100644
index 0000000..4408e32
--- /dev/null
+++ b/debian/patches/any/cvs-catopen.diff
@@ -0,0 +1,208 @@
+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.
+
+--- a/catgets/Makefile
++++ b/catgets/Makefile
+@@ -50,15 +50,15 @@
+ 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,8 @@
+ $(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
+--- 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 @@
+   __nl_catd result;
+   const char *env_var = NULL;
+   const char *nlspath = NULL;
++  char *tmp = NULL;
+ 
+   if (strchr (cat_name, '/') == NULL)
+     {
+@@ -55,7 +55,10 @@
+ 	{
+ 	  /* 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;
+@@ -66,16 +69,18 @@
+ 
+   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;
+ }
+ 
+--- a/catgets/open_catalog.c
++++ b/catgets/open_catalog.c
+@@ -48,6 +48,7 @@
+   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 @@
+   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')
+ 	{
+@@ -189,7 +190,10 @@
+ 
+   /* 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 @@
+   /* Release the lock again.  */
+  close_unlock_return:
+   close_not_cancel_no_status (fd);
++  free (buf);
+ 
+   return result;
+ }
+--- 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 @@
+ };
+ #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 @@
+ 	}
+     }
+ 
++  result += do_bz17905 ();
+   return result;
+ }
diff --git a/debian/patches/series b/debian/patches/series
index dc846f8..0d0c9b1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -411,3 +411,4 @@ any/cvs-ld_pointer_guard.diff
 any/cvs-strxfrm-buffer-overflows.diff
 any/cvs-strftime.diff
 any/cvs-hcreate.diff
+any/cvs-catopen.diff

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


Reply to: