|
@@ -0,0 +1,155 @@
|
|
|
+From d36c75fc0d44deec29635dd239b0fbd206ca49b7 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
|
|
|
+
|
|
|
+Upstream-Status: Backport
|
|
|
+CVE: CVE-2015-8776
|
|
|
+[Yocto # 8980]
|
|
|
+
|
|
|
+https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d36c75fc0d44deec29635dd239b0fbd206ca49b7
|
|
|
+
|
|
|
+Signed-off-by: Armin Kuster <akuster@mvista.com>
|
|
|
+
|
|
|
+---
|
|
|
+ ChangeLog | 8 ++++++++
|
|
|
+ NEWS | 2 +-
|
|
|
+ time/strftime_l.c | 20 +++++++++++++-------
|
|
|
+ time/tst-strftime.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
+ 4 files changed, 73 insertions(+), 9 deletions(-)
|
|
|
+
|
|
|
+Index: git/ChangeLog
|
|
|
+===================================================================
|
|
|
+--- git.orig/ChangeLog
|
|
|
++++ git/ChangeLog
|
|
|
+@@ -1,3 +1,11 @@
|
|
|
++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-12-04 Joseph Myers <joseph@codesourcery.com>
|
|
|
+
|
|
|
+ [BZ #16961]
|
|
|
+Index: git/time/strftime_l.c
|
|
|
+===================================================================
|
|
|
+--- git.orig/time/strftime_l.c
|
|
|
++++ git/time/strftime_l.c
|
|
|
+@@ -514,13 +514,17 @@ __strftime_internal (s, maxsize, format,
|
|
|
+ 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)))
|
|
|
+@@ -530,8 +534,10 @@ __strftime_internal (s, maxsize, format,
|
|
|
+ # 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))
|
|
|
+@@ -1325,7 +1331,7 @@ __strftime_internal (s, maxsize, format,
|
|
|
+ *tzset_called = true;
|
|
|
+ }
|
|
|
+ # endif
|
|
|
+- zone = tzname[tp->tm_isdst];
|
|
|
++ zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?";
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+ if (! zone)
|
|
|
+Index: git/time/tst-strftime.c
|
|
|
+===================================================================
|
|
|
+--- git.orig/time/tst-strftime.c
|
|
|
++++ git/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 ()
|