From: Daiki Ueno Date: Fri, 5 Dec 2014 06:18:55 +0000 (+0900) Subject: msgunfmt: Avoid integer overflow using xsize X-Git-Tag: v0.19.4~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7c8a70bc2d0fb36d16c406a6f3bee6cf998c8231;p=thirdparty%2Fgettext.git msgunfmt: Avoid integer overflow using xsize * read-mo.c (get_uint32, get_sysdep_string): Use xsum to avoid integer overflow, when checking length and offset fields. Reported by Jakub Wilk at: . --- diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index b7b4505f0..245252844 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,11 @@ +2014-12-05 Daiki Ueno + + msgunfmt: Avoid integer overflow using xsize + * read-mo.c (get_uint32, get_sysdep_string): Use xsum to avoid + integer overflow, when checking length and offset fields. + Reported by Jakub Wilk at: + . + 2014-12-04 Daiki Ueno libgettextsrc: Follow plural.c -> pluralx.c file name change diff --git a/gettext-tools/src/read-mo.c b/gettext-tools/src/read-mo.c index c867236d8..b97bbadc3 100644 --- a/gettext-tools/src/read-mo.c +++ b/gettext-tools/src/read-mo.c @@ -101,8 +101,9 @@ static nls_uint32 get_uint32 (const struct binary_mo_file *bfp, size_t offset) { nls_uint32 b0, b1, b2, b3; + size_t end = xsum (offset, 4); - if (offset + 4 > bfp->size) + if (size_overflow_p (end) || end > bfp->size) error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename); b0 = *(unsigned char *) (bfp->data + offset + 0); @@ -156,6 +157,7 @@ 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 ss_end; size_t n; length += segsize; @@ -170,7 +172,8 @@ get_sysdep_string (const struct binary_mo_file *bfp, size_t offset, sysdep_segment_offset = header->sysdep_segments_offset + sysdepref * 8; ss_length = get_uint32 (bfp, sysdep_segment_offset); ss_offset = get_uint32 (bfp, sysdep_segment_offset + 4); - if (ss_offset + ss_length > bfp->size) + 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')) { @@ -195,9 +198,10 @@ 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 (s_offset + segsize > bfp->size) + 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;