diff --git a/emacs.changes b/emacs.changes index 79ea69c..2fb8a3c 100644 --- a/emacs.changes +++ b/emacs.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue May 2 11:02:57 UTC 2017 - werner@suse.de + +- Add patch gnulib.git-94e01571.patch to fix CVE-2017-7476 + ------------------------------------------------------------------- Wed Apr 26 07:33:45 UTC 2017 - werner@suse.de diff --git a/emacs.spec b/emacs.spec index 1842e09..911e098 100644 --- a/emacs.spec +++ b/emacs.spec @@ -127,6 +127,8 @@ Patch23: emacs-25.1-custom-fonts.patch # but that is because we ship /usr/include/ImageMagick-7/wand compat # symlink Patch24: emacs-25.2-ImageMagick7.patch +# PATCH-FIX-UPSTREAM-GNULIB CVE-2017-7476 +Patch25: gnulib.git-94e01571.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %{expand: %%global include_info %(test -s /usr/share/info/info.info* && echo 0 || echo 1)} @@ -240,8 +242,9 @@ and most assembler-like syntaxes. %patch16 -p0 -b .flyspell %patch22 -p0 -b .obsolate %patch23 -p0 -b .custfnt -%patch -p0 -b .0 %patch24 -p1 +%patch25 -p0 +%patch -p0 -b .0 %if %{without autoconf} # We don't want to run autoconf diff --git a/gnulib.git-94e01571.patch b/gnulib.git-94e01571.patch new file mode 100644 index 0000000..ed71415 --- /dev/null +++ b/gnulib.git-94e01571.patch @@ -0,0 +1,85 @@ +From 94e01571507835ff59dd8ce2a0b56a4b566965a4 Mon Sep 17 00:00:00 2001 +From: =?utf8?q?P=C3=A1draig=20Brady?= +Date: Mon, 24 Apr 2017 01:43:36 -0700 +Subject: [PATCH] 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 +--- + lib/time_rz.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- lib/time_rz.c ++++ lib/time_rz.c 2017-05-02 11:00:09.386018503 +0000 +@@ -27,6 +27,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -34,6 +35,10 @@ + + #include "time-internal.h" + ++#ifndef SIZE_MAX ++# define SIZE_MAX ((size_t) -1) ++#endif ++ + #if !HAVE_TZSET + static void tzset (void) { } + #endif +@@ -42,7 +47,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) }; +@@ -149,7 +154,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 + {