]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
msgunfmt: Avoid integer overflow using xsize
authorDaiki Ueno <ueno@gnu.org>
Fri, 5 Dec 2014 06:18:55 +0000 (15:18 +0900)
committerDaiki Ueno <ueno@gnu.org>
Fri, 5 Dec 2014 06:18:55 +0000 (15:18 +0900)
* 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:
<https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=772088>.

gettext-tools/src/ChangeLog
gettext-tools/src/read-mo.c

index b7b4505f073a1bd7dad6c663b61fe6fec8df59d9..245252844b1dc264ab0865ecedc04305a7ae4266 100644 (file)
@@ -1,3 +1,11 @@
+2014-12-05  Daiki Ueno  <ueno@gnu.org>
+
+       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:
+       <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=772088>.
+
 2014-12-04  Daiki Ueno  <ueno@gnu.org>
 
        libgettextsrc: Follow plural.c -> pluralx.c file name change
index c867236d85d8351d4905a5ba9f6157230af4643d..b97bbadc32a8197aa821af01d989fadfc72400ae 100644 (file)
@@ -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;