Fix decoding of Windows resources.
authorNick Clifton <nickc@redhat.com>
Thu, 28 Jul 2016 14:37:16 +0000 (15:37 +0100)
committerNick Clifton <nickc@redhat.com>
Thu, 28 Jul 2016 14:37:16 +0000 (15:37 +0100)
PR binutils/17512
* rescoff.c (read_coff_res_dir): Fix detection of buffer overrun.
* resbin.c (bin_to_res_version): Allow for the padded length of a
version block to be longer than the recorded length.  Skip padding
bytes.

binutils/ChangeLog
binutils/resbin.c
binutils/rescoff.c

index 43ed236cc7cc869f280fcfe9173abd905a13b22f..358b5a4930d886dbb339ce6b7eb642742ded7ba7 100644 (file)
@@ -1,3 +1,11 @@
+2016-07-28  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/17512
+       * rescoff.c (read_coff_res_dir): Fix detection of buffer overrun.
+       * resbin.c (bin_to_res_version): Allow for the padded length of a
+       version block to be longer than the recorded length.  Skip padding
+       bytes.
+
 2016-07-21  H.J. Lu  <hongjiu.lu@intel.com>
 
        * configure: Regenerated.
index 03d3010d192bf9e1eb911020add2a734cc19aa08..9ca540853d349ffc1c99ed94df77cc99d5c1462d 100644 (file)
@@ -961,9 +961,10 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
   get_version_header (wrbfd, data, length, "VS_VERSION_INFO",
                      (unichar **) NULL, &verlen, &vallen, &type, &off);
 
-  if ((unsigned int) verlen != length)
-    fatal (_("version length %d does not match resource length %lu"),
-          (int) verlen, (unsigned long) length);
+  /* PR 17512: The verlen field does not include padding length.  */
+  if (verlen > length)
+    fatal (_("version length %lu greater than resource length %lu"),
+          verlen, length);
 
   if (type != 0)
     fatal (_("unexpected version type %d"), (int) type);
@@ -1164,8 +1165,15 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
              vallen -= 4;
            }
        }
+      else if (ch == 0)
+       {
+         if (length == 8)
+           /* Padding - skip.  */
+           break;
+         fatal (_("nul bytes found in version string"));
+       }
       else
-       fatal (_("unexpected version string"));
+       fatal (_("unexpected version string character: %x"), ch);
 
       vi->next = NULL;
       *pp = vi;
index 74a61a7be5d1fd0e87d31855de3c5a77dcf30fae..9151eab93fcbc2769b26fd441d82e97b7b252dcb 100644 (file)
@@ -249,7 +249,7 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
       for (j = 0; j < length; j++)
        {
          /* PR 17512: file: 05dc4a16.  */
-         if (length < 0 || ers >= (bfd_byte *) ere || ers + j * 2 + 4 >= (bfd_byte *) ere)
+         if (length < 0 || ers >= flaginfo->data_end || ers + j * 2 + 4 >= flaginfo->data_end)
            overrun (flaginfo, _("resource name"));
          re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
        }