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

[glibc] 01/03: patches/any/cvs-strftime.diff: new patch from upstream to fix segmentation fault caused by passing out-of-range data to strftime() (CVE-2015-8776). Closes: #812445.



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

aurel32 pushed a commit to branch wheezy
in repository glibc.

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

    patches/any/cvs-strftime.diff: new patch from upstream to fix segmentation fault caused by passing out-of-range data to strftime() (CVE-2015-8776).  Closes: #812445.
---
 debian/changelog                     |   9 +++
 debian/patches/any/cvs-strftime.diff | 127 +++++++++++++++++++++++++++++++++++
 debian/patches/series                |   1 +
 3 files changed, 137 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 1632823..dc60326 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+eglibc (2.13-38+deb7u10) UNRELEASED; urgency=medium
+
+  [ Aurelien Jarno ]
+  * patches/any/cvs-strftime.diff: new patch from upstream to fix
+    segmentation fault caused by passing out-of-range data to strftime()
+    (CVE-2015-8776).  Closes: #812445.
+
+ -- Aurelien Jarno <aurel32@debian.org>  Sun, 31 Jan 2016 12:55:29 +0100
+
 eglibc (2.13-38+deb7u9) wheezy; urgency=medium
 
   [ Aurelien Jarno ]
diff --git a/debian/patches/any/cvs-strftime.diff b/debian/patches/any/cvs-strftime.diff
new file mode 100644
index 0000000..c7b4cec
--- /dev/null
+++ b/debian/patches/any/cvs-strftime.diff
@@ -0,0 +1,127 @@
+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.
+
+--- 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 ()
+-- 
+2.7.0
+
diff --git a/debian/patches/series b/debian/patches/series
index 18084c4..668cc56 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -409,3 +409,4 @@ any/cvs-fnmatch-overflow.diff
 any/cvs-_IO_wstr_overflow.diff
 any/cvs-ld_pointer_guard.diff
 any/cvs-strxfrm-buffer-overflows.diff
+any/cvs-strftime.diff

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


Reply to: