From d8863ca283371dc4e68c3ff14c165c78d38ac80e55c1514ba907b3c5fe3d2fdc Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Wed, 17 May 2017 08:45:29 +0000 Subject: [PATCH] Accepting request 492649 from Base:System 1 OBS-URL: https://build.opensuse.org/request/show/492649 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/coreutils?expand=0&rev=123 --- ...017-7476-out-of-bounds-with-large-tz.patch | 216 ++++++++++++++++++ coreutils-testsuite.changes | 8 + coreutils-testsuite.spec | 7 + coreutils.changes | 8 + coreutils.spec | 7 + 5 files changed, 246 insertions(+) create mode 100644 coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch diff --git a/coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch b/coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch new file mode 100644 index 0000000..3d27a8f --- /dev/null +++ b/coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch @@ -0,0 +1,216 @@ +# Upstream fix on top of coreutils-v8.27: +# Add upstream patch to fix an heap overflow security issue +# in date(1) and touch(1) with a large TZ variable +# (CVE-2017-7476, rh#1444774, boo#1037124). + +This issue is already fixed upstream, so here in openSUSE +we're just picking up the patches: + +* [PATCH 1/2] Upstream gnulib fix: + http://git.sv.gnu.org/cgit/gnulib.git/commit/?id=94e015715078 + + FWIW, this patch has been picked up by upstream coreutils by + the following update to latest gnulib: + http://git.sv.gnu.org/cgit/coreutils.git/commit/?id=5d4be52a982e + +* [PATCH 2/2] Upstream coreutils test: + http://git.sv.gnu.org/cgit/coreutils.git/commit/?id=9287ef2b1707 + +This downstream patch squashes both commits into one. +Here are the original commit messages. + +================================================================================ +From 94e01571507835ff59dd8ce2a0b56a4b566965a4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Mon, 24 Apr 2017 01:43:36 -0700 +Subject: [PATCH 1/2] time_rz: fix heap buffer overflow vulnerability + +This issue has been assigned CVE-2017-7476 and was +detected with American Fuzzy Lop 2.41b run on the +coreutils date(1) program with ASAN enabled. + + ERROR: AddressSanitizer: heap-buffer-overflow on address 0x... + WRITE of size 8 at 0x60d00000cff8 thread T0 + #1 0x443020 in extend_abbrs lib/time_rz.c:88 + #2 0x443356 in save_abbr lib/time_rz.c:155 + #3 0x44393f in localtime_rz lib/time_rz.c:290 + #4 0x41e4fe in parse_datetime2 lib/parse-datetime.y:1798 + +A minimized reproducer is the following 120 byte TZ value, +which goes beyond the value of ABBR_SIZE_MIN (119) on x86_64. +Extend the aa...b portion to overwrite more of the heap. + + date -d $(printf 'TZ="aaa%020daaaaaab%089d"') + +localtime_rz and mktime_z were affected since commit 4bc76593. +parse_datetime was affected since commit 4e6e16b3f. + +* lib/time_rz.c (save_abbr): Rearrange the calculation determining +whether there is enough buffer space available. The rearrangement +ensures we're only dealing with positive numbers, thus avoiding +the problematic promotion of signed to unsigned causing an invalid +comparison when zone_copy is more than ABBR_SIZE_MIN bytes beyond +the start of the buffer. +* tests/test-parse-datetime.c (main): Add a test case written by +Paul Eggert, which overwrites enough of the heap so that +standard glibc will fail with "free(): invalid pointer" +without the patch applied. +Reported and analyzed at https://bugzilla.redhat.com/1444774 + +================================================================================ +From 9287ef2b1707e2a222f8ae776ce3785abcb16fba Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Wed, 26 Apr 2017 20:51:39 -0700 +Subject: [PATCH 2/2] date,touch: test and document large TZ security issue + +Add a test for CVE-2017-7476 which was fixed in gnulib at: +http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=94e01571 + +* tests/misc/date-tz.sh: Add a new test which overwrites enough +of the heap to trigger a segfault, even without ASAN enabled. +* tests/local.mk: Reference the new test. +* NEWS: Mention the bug fix. + +--- + NEWS | 9 +++++++++ + gnulib-tests/test-parse-datetime.c | 16 ++++++++++++++++ + lib/time_rz.c | 15 +++++++++++++-- + tests/local.mk | 1 + + tests/misc/date-tz.sh | 26 ++++++++++++++++++++++++++ + 5 files changed, 65 insertions(+), 2 deletions(-) + +Index: NEWS +=================================================================== +--- NEWS.orig ++++ NEWS +@@ -1,5 +1,14 @@ + GNU coreutils NEWS -*- outline -*- + ++* Noteworthy openSUSE changes after release 8.27 [downstream] ++ ++** Bug fixes ++ ++ date and touch no longer overwrite the heap with large ++ user specified TZ values (CVE-2017-7476). ++ [bug introduced in coreutils-8.27] ++ ++ + * Noteworthy changes in release 8.27 (2017-03-08) [stable] + + ** Bug fixes +Index: gnulib-tests/test-parse-datetime.c +=================================================================== +--- gnulib-tests/test-parse-datetime.c.orig ++++ gnulib-tests/test-parse-datetime.c +@@ -432,5 +432,21 @@ main (int argc _GL_UNUSED, char **argv) + ASSERT ( parse_datetime (&result, "TZ=\"\\\\\"", &now)); + ASSERT ( parse_datetime (&result, "TZ=\"\\\"\"", &now)); + ++ /* Outlandishly-long time zone abbreviations should not cause problems. */ ++ { ++ static char const bufprefix[] = "TZ=\""; ++ enum { tzname_len = 2000 }; ++ static char const bufsuffix[] = "0\" 1970-01-01 01:02:03.123456789"; ++ enum { bufsize = sizeof bufprefix - 1 + tzname_len + sizeof bufsuffix }; ++ char buf[bufsize]; ++ memcpy (buf, bufprefix, sizeof bufprefix - 1); ++ memset (buf + sizeof bufprefix - 1, 'X', tzname_len); ++ strcpy (buf + bufsize - sizeof bufsuffix, bufsuffix); ++ ASSERT (parse_datetime (&result, buf, &now)); ++ LOG (buf, now, result); ++ ASSERT (result.tv_sec == 1 * 60 * 60 + 2 * 60 + 3 ++ && result.tv_nsec == 123456789); ++ } ++ + return 0; + } +Index: lib/time_rz.c +=================================================================== +--- lib/time_rz.c.orig ++++ lib/time_rz.c +@@ -27,6 +27,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -35,6 +36,10 @@ + #include "flexmember.h" + #include "time-internal.h" + ++#ifndef SIZE_MAX ++# define SIZE_MAX ((size_t) -1) ++#endif ++ + #if !HAVE_TZSET + static void tzset (void) { } + #endif +@@ -43,7 +48,7 @@ static void tzset (void) { } + the largest "small" request for the GNU C library malloc. */ + enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; + +-/* Minimum size of the ABBRS member of struct abbr. ABBRS is larger ++/* Minimum size of the ABBRS member of struct tm_zone. ABBRS is larger + only in the unlikely case where an abbreviation longer than this is + used. */ + enum { ABBR_SIZE_MIN = DEFAULT_MXFAST - offsetof (struct tm_zone, abbrs) }; +@@ -150,7 +155,13 @@ save_abbr (timezone_t tz, struct tm *tm) + if (! (*zone_copy || (zone_copy == tz->abbrs && tz->tz_is_set))) + { + size_t zone_size = strlen (zone) + 1; +- if (zone_size < tz->abbrs + ABBR_SIZE_MIN - zone_copy) ++ size_t zone_used = zone_copy - tz->abbrs; ++ if (SIZE_MAX - zone_used < zone_size) ++ { ++ errno = ENOMEM; ++ return false; ++ } ++ if (zone_used + zone_size < ABBR_SIZE_MIN) + extend_abbrs (zone_copy, zone, zone_size); + else + { +Index: tests/local.mk +=================================================================== +--- tests/local.mk.orig ++++ tests/local.mk +@@ -282,6 +282,7 @@ all_tests = \ + tests/misc/csplit-suppress-matched.pl \ + tests/misc/date-debug.sh \ + tests/misc/date-sec.sh \ ++ tests/misc/date-tz.sh \ + tests/misc/dircolors.pl \ + tests/misc/dirname.pl \ + tests/misc/env-null.sh \ +Index: tests/misc/date-tz.sh +=================================================================== +--- /dev/null ++++ tests/misc/date-tz.sh +@@ -0,0 +1,26 @@ ++#!/bin/sh ++# Verify TZ processing. ++ ++# Copyright (C) 2017 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program 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 General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ date ++ ++# coreutils-8.27 would overwrite the heap with large TZ values ++tz_long=$(printf '%2000s' | tr ' ' a) ++date -d "TZ=\"${tz_long}0\" 2017" || fail=1 ++ ++Exit $fail diff --git a/coreutils-testsuite.changes b/coreutils-testsuite.changes index 7c11879..5686ceb 100644 --- a/coreutils-testsuite.changes +++ b/coreutils-testsuite.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue May 2 21:29:32 UTC 2017 - mail@bernhard-voelker.de + +- coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch: + Add upstream patch to fix an heap overflow security issue + in date(1) and touch(1) with a large TZ variable + (CVE-2017-7476, rh#1444774, boo#1037124). + ------------------------------------------------------------------- Fri Mar 10 09:42:51 UTC 2017 - mail@bernhard-voelker.de diff --git a/coreutils-testsuite.spec b/coreutils-testsuite.spec index 554bed6..d1b9ffd 100644 --- a/coreutils-testsuite.spec +++ b/coreutils-testsuite.spec @@ -133,6 +133,12 @@ Patch501: coreutils-test_without_valgrind.patch # Avoid a FP of tests/misc/date-debug.sh with newer timezone-2017a. Patch700: coreutils-tests-port-to-timezone-2017a.patch +# Upstream fix on top of coreutils-v8.27: +# Add upstream patch to fix an heap overflow security issue +# in date(1) and touch(1) with a large TZ variable +# (CVE-2017-7476, rh#1444774, boo#1037124). +Patch710: coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch + # ================================================ %description These are the GNU core utilities. This package is the union of @@ -176,6 +182,7 @@ the GNU fileutils, sh-utils, and textutils packages. %patch501 %patch700 +%patch710 #???## We need to statically link to gmp, otherwise we have a build loop #???#sed -i s,'$(LIB_GMP)',%%{_libdir}/libgmp.a,g Makefile.in diff --git a/coreutils.changes b/coreutils.changes index 7c11879..5686ceb 100644 --- a/coreutils.changes +++ b/coreutils.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue May 2 21:29:32 UTC 2017 - mail@bernhard-voelker.de + +- coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch: + Add upstream patch to fix an heap overflow security issue + in date(1) and touch(1) with a large TZ variable + (CVE-2017-7476, rh#1444774, boo#1037124). + ------------------------------------------------------------------- Fri Mar 10 09:42:51 UTC 2017 - mail@bernhard-voelker.de diff --git a/coreutils.spec b/coreutils.spec index c98d10f..c765a5c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -133,6 +133,12 @@ Patch501: coreutils-test_without_valgrind.patch # Avoid a FP of tests/misc/date-debug.sh with newer timezone-2017a. Patch700: coreutils-tests-port-to-timezone-2017a.patch +# Upstream fix on top of coreutils-v8.27: +# Add upstream patch to fix an heap overflow security issue +# in date(1) and touch(1) with a large TZ variable +# (CVE-2017-7476, rh#1444774, boo#1037124). +Patch710: coreutils-cve-2017-7476-out-of-bounds-with-large-tz.patch + # ================================================ %description These are the GNU core utilities. This package is the union of @@ -176,6 +182,7 @@ the GNU fileutils, sh-utils, and textutils packages. %patch501 %patch700 +%patch710 #???## We need to statically link to gmp, otherwise we have a build loop #???#sed -i s,'$(LIB_GMP)',%%{_libdir}/libgmp.a,g Makefile.in