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 0000000..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 2>mu-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 0000000000000000000000000000000000000000..3cb4e94db7aca41f9b7d01c53c8c6166e056a7fc GIT binary patch literal 48 kcmca7#4?ou2pEA_28dNa93apEVvrb!27>=Uz)%5%0C+_Q5C8xG literal 0 HcmV?d00001 -- 2.1.0