diff --git a/gnu-system.am b/gnu-system.am index 3a34f5f746..ad9348fb9a 100644 --- a/gnu-system.am +++ b/gnu-system.am @@ -431,6 +431,7 @@ dist_patch_DATA = \ gnu/packages/patches/gcc-libvtv-runpath.patch \ gnu/packages/patches/gcc-5.0-libvtv-runpath.patch \ gnu/packages/patches/geoclue-config.patch \ + gnu/packages/patches/gettext-msgunfmt.patch \ gnu/packages/patches/ghostscript-runpath.patch \ gnu/packages/patches/gitolite-openssh-6.8-compat.patch \ gnu/packages/patches/glib-tests-desktop.patch \ diff --git a/gnu/packages/gettext.scm b/gnu/packages/gettext.scm index 3a96cd613c..9289946178 100644 --- a/gnu/packages/gettext.scm +++ b/gnu/packages/gettext.scm @@ -42,7 +42,8 @@ (define-public gnu-gettext version ".tar.gz")) (sha256 (base32 - "0gvz86m4cs8bdf3mwmwsyx6lrq4ydfxgadrgd9jlx32z3bnz3jca")))) + "0gvz86m4cs8bdf3mwmwsyx6lrq4ydfxgadrgd9jlx32z3bnz3jca")) + (patches (list (search-patch "gettext-msgunfmt.patch"))))) (build-system gnu-build-system) (inputs `(("expat" ,expat))) diff --git a/gnu/packages/patches/gettext-msgunfmt.patch b/gnu/packages/patches/gettext-msgunfmt.patch new file mode 100644 index 0000000000..4a50abddc2 --- /dev/null +++ b/gnu/packages/patches/gettext-msgunfmt.patch @@ -0,0 +1,58 @@ +From . + +2015-03-11 Daiki Ueno + + msgunfmt: Check allocated size for static segment + Reported by Max Lin in: + http://lists.gnu.org/archive/html/bug-gettext/2015-03/msg00005.html + * read-mo.c (get_sysdep_string): Check if the embedded segment + size is valid, before adding it to the string length. + +diff --git a/gettext-tools/src/read-mo.c b/gettext-tools/src/read-mo.c +index b97bbad..1c024a8 100644 +--- a/gettext-tools/src/read-mo.c ++++ b/gettext-tools/src/read-mo.c +@@ -149,6 +149,7 @@ get_sysdep_string (const struct binary_mo_file *bfp, size_t offset, + nls_uint32 s_offset; + + /* Compute the length. */ ++ s_offset = get_uint32 (bfp, offset); + length = 0; + for (i = 4; ; i += 8) + { +@@ -158,9 +159,14 @@ get_sysdep_string (const struct binary_mo_file *bfp, size_t offset, + nls_uint32 ss_length; + nls_uint32 ss_offset; + size_t ss_end; ++ size_t s_end; + size_t n; + ++ s_end = xsum (s_offset, segsize); ++ if (size_overflow_p (s_end) || s_end > bfp->size) ++ error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename); + length += segsize; ++ s_offset += segsize; + + if (sysdepref == SEGMENTS_END) + break; +@@ -175,7 +181,7 @@ get_sysdep_string (const struct binary_mo_file *bfp, size_t offset, + ss_end = xsum (ss_offset, ss_length); + if (size_overflow_p (ss_end) || ss_end > bfp->size) + error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename); +- if (!(ss_length > 0 && bfp->data[ss_offset + ss_length - 1] == '\0')) ++ if (!(ss_length > 0 && bfp->data[ss_end - 1] == '\0')) + { + char location[30]; + sprintf (location, "sysdep_segment[%u]", (unsigned int) sysdepref); +@@ -198,11 +204,8 @@ get_sysdep_string (const struct binary_mo_file *bfp, size_t offset, + nls_uint32 sysdep_segment_offset; + nls_uint32 ss_length; + nls_uint32 ss_offset; +- size_t s_end = xsum (s_offset, segsize); + size_t n; + +- if (size_overflow_p (s_end) || s_end > bfp->size) +- error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename); + memcpy (p, bfp->data + s_offset, segsize); + p += segsize; + s_offset += segsize;