Bug#769901: gettext: msgunfmt segfault

2014-11-17 Thread Jakub Wilk

Package: gettext
Version: 0.19.3-1

The attached (slightly corrupted) MO file crashes msgunfmt:

$ msgunfmt messages.mo
Segmentation fault

I suspect there's a integer overflow somewhere.


This bug was brought to you by American fuzzy lop:
http://lcamtuf.coredump.cx/afl/


-- System Information:
Debian Release: jessie/sid
 APT prefers unstable
 APT policy: (990, 'unstable'), (500, 'experimental')
Architecture: i386 (x86_64)
Foreign Architectures: amd64

Kernel: Linux 3.2.0-4-amd64 (SMP w/2 CPU cores)
Locale: LANG=C, LC_CTYPE=pl_PL.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages gettext depends on:
ii  dpkg   1.17.21
ii  gettext-base   0.19.3-1
ii  install-info   5.2.0.dfsg.1-5
ii  libc6  2.19-13
ii  libcroco3  0.6.8-3
ii  libglib2.0-0   2.42.1-1
ii  libgomp1   4.9.2-1
ii  libncurses55.9+20140913-1
ii  libtinfo5  5.9+20140913-1
ii  libunistring0  0.9.3-5.2
ii  libxml22.9.2+dfsg1-1

Versions of packages gettext recommends:
ii  autopoint 0.19.3-1
ii  curl  7.38.0-3
ii  libasprintf-dev   0.19.3-1
ii  libgettextpo-dev  0.19.3-1
ii  wget  1.16-3

--
Jakub Wilk


messages.mo
Description: Binary data


Bug#769901: gettext: msgunfmt segfault

2014-11-17 Thread Daiki Ueno
Jakub Wilk jw...@debian.org writes:

 The attached (slightly corrupted) MO file crashes msgunfmt:

 $ msgunfmt messages.mo
 Segmentation fault

Thanks for the report.  It seems like a long standing issue (I can
reproduce it even with 0.17).

 I suspect there's a integer overflow somewhere.

Yes.  I'm attaching a patch and a test-case.

Regards,
--
Daiki Ueno
From 2a760b57161a2b4769e0b1c74db243b213733ef3 Mon Sep 17 00:00:00 2001
From: Daiki Ueno u...@gnu.org
Date: Tue, 18 Nov 2014 12:11:22 +0900
Subject: [PATCH 1/2] read-mo: Check size_t overflow

* read-mo.c: Include xsize.h.
(get_string): Use xsum3 to avoid overflow, when checking length
and offset fields.
Reported by Jakub Wilk at:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=769901.
---
 gettext-tools/src/ChangeLog | 8 
 gettext-tools/src/read-mo.c | 4 +++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog
index d392ba7..e250ae1 100644
--- a/gettext-tools/src/ChangeLog
+++ b/gettext-tools/src/ChangeLog
@@ -1,3 +1,11 @@
+2014-11-18  Daiki Ueno  u...@gnu.org
+
+	* read-mo.c: Include xsize.h.
+	(get_string): Use xsum3 to avoid overflow, when checking length
+	and offset fields.
+	Reported by Jakub Wilk at:
+	https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=769901.
+
 2014-10-28  Daiki Ueno  u...@gnu.org
 
 	xgettext: Allow plural extraction from a single argument function
diff --git a/gettext-tools/src/read-mo.c b/gettext-tools/src/read-mo.c
index 9e0220c..c867236 100644
--- a/gettext-tools/src/read-mo.c
+++ b/gettext-tools/src/read-mo.c
@@ -38,6 +38,7 @@
 #include message.h
 #include format.h
 #include gettext.h
+#include xsize.h
 
 #define _(str) gettext (str)
 
@@ -121,8 +122,9 @@ get_string (const struct binary_mo_file *bfp, size_t offset, size_t *lengthp)
   /* See 'struct string_desc'.  */
   nls_uint32 s_length = get_uint32 (bfp, offset);
   nls_uint32 s_offset = get_uint32 (bfp, offset + 4);
+  size_t s_end = xsum3 (s_offset, s_length, 1);
 
-  if (s_offset + s_length + 1  bfp-size)
+  if (size_overflow_p (s_end) || s_end  bfp-size)
 error (EXIT_FAILURE, 0, _(file \%s\ is truncated), bfp-filename);
   if (bfp-data[s_offset + s_length] != '\0')
 error (EXIT_FAILURE, 0,
-- 
2.1.0

From 7674ef72f25b2ff2d7ebfc271a14b0e6e9598473 Mon Sep 17 00:00:00 2001
From: Daiki Ueno u...@gnu.org
Date: Tue, 18 Nov 2014 12:29:32 +0900
Subject: [PATCH 2/2] tests: Add test for integer overflow when reading MO file

* msgunfmt-3: New file.
* Makefile.am (TESTS): Add new test.
(EXTRA_DIST): Add data file for msgunfmt-3.
---
 gettext-tools/tests/ChangeLog   |   7 +++
 gettext-tools/tests/Makefile.am |   4 ++--
 gettext-tools/tests/msgunfmt-3  |   9 +
 gettext-tools/tests/overflow.mo | Bin 0 - 48 bytes
 4 files changed, 18 insertions(+), 2 deletions(-)
 create mode 100755 gettext-tools/tests/msgunfmt-3
 create mode 100644 gettext-tools/tests/overflow.mo

diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog
index d6d6788..cde4819 100644
--- a/gettext-tools/tests/ChangeLog
+++ b/gettext-tools/tests/ChangeLog
@@ -1,3 +1,10 @@
+2014-11-18  Daiki Ueno  u...@gnu.org
+
+	tests: Add test for integer overflow when reading MO file
+	* msgunfmt-3: New file.
+	* Makefile.am (TESTS): Add new test.
+	(EXTRA_DIST): Add data file for msgunfmt-3.
+
 2014-10-28  Daiki Ueno  u...@gnu.org
 
 	xgettext: Allow plural extraction from a single argument function
diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am
index 3df6e1f..910dde0 100644
--- a/gettext-tools/tests/Makefile.am
+++ b/gettext-tools/tests/Makefile.am
@@ -63,7 +63,7 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
 	msgmerge-properties-1 msgmerge-properties-2 \
 	msgmerge-update-1 msgmerge-update-2 msgmerge-update-3 \
 	msgmerge-update-4 \
-	msgunfmt-1 msgunfmt-2 \
+	msgunfmt-1 msgunfmt-2 msgunfmt-3 \
 	msgunfmt-csharp-1 \
 	msgunfmt-java-1 \
 	msgunfmt-properties-1 \
@@ -145,7 +145,7 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
 	autopoint-1 autopoint-2 autopoint-3
 
 EXTRA_DIST += init.sh init.cfg $(TESTS) \
-	test.mo xg-c-1.ok.po mex-test2.ok \
+	test.mo overflow.mo xg-c-1.ok.po mex-test2.ok \
 	mm-ko.ascii.pot mm-ko.euc-kr.po mm-ko-comp.euc-kr.po \
 	mm-viet.comp.po mm-viet.pot mm-viet.out \
 	msguniq-a.in msguniq-a.inp msguniq-a.out \
diff --git a/gettext-tools/tests/msgunfmt-3 b/gettext-tools/tests/msgunfmt-3
new file mode 100755
index 000..a1b98d7
--- /dev/null
+++ b/gettext-tools/tests/msgunfmt-3
@@ -0,0 +1,9 @@
+#! /bin/sh
+. ${srcdir=.}/init.sh; path_prepend_ . ../src
+
+# Test invalid or incomplete input
+
+: ${MSGUNFMT=msgunfmt}
+LANGUAGE= LC_ALL=C ${MSGUNFMT} ../overflow.mo 2mu-3.err /dev/null
+test $? != 0 || exit 1
+grep ' is truncated' mu-3.err /dev/null || exit 1
diff --git a/gettext-tools/tests/overflow.mo b/gettext-tools/tests/overflow.mo
new file mode 100644
index