]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Sanity check windows resource version len
authorAlan Modra <amodra@gmail.com>
Sun, 17 Aug 2025 12:04:17 +0000 (21:34 +0930)
committerAlan Modra <amodra@gmail.com>
Sun, 17 Aug 2025 13:02:43 +0000 (22:32 +0930)
oss-fuzz generated a total length field of 32, when the header was 40
bytes.  Subtracting gave -8ul for the remaining length..

I think we should be sanity checking the total length given in the
header against the remaining buffer length and the size of the header
each time get_version_header is called.

Possibly vallen should be sanity checked inside get_version_header
too, but I'll leave that to someone else.

PR 27686
* resbin.c (bin_to_res_version): Correct error message arg.
Move len vs. buffer length sanity check..
(get_version_header): ..to here.  Also sanity check len
against off.

binutils/resbin.c

index fa77cd43d23f3839a30877fd9534cd241d16745e..02905b9c9de5e8e245d40c7850d8199a8e33f9f1 100644 (file)
@@ -1060,8 +1060,14 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data,
   *vallen = windres_get_16 (wrbfd, data + 2);
   *type = windres_get_16 (wrbfd, data + 4);
 
-  *off = 6;
+  if (*len > length)
+    {
+      non_fatal (_("version length %lu greater than resource length %lu"),
+                (unsigned long) *len, (unsigned long) length);
+      return false;
+    }
 
+  *off = 6;
   length -= 6;
   data += 6;
 
@@ -1101,6 +1107,14 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data,
     }
 
   *off = (*off + 3) &~ 3;
+
+  if (*len < *off)
+    {
+      non_fatal (_("version length %lu does not cover header length %lu"),
+                (unsigned long) *len, (unsigned long) *off);
+      return false;
+    }
+
   return true;
 }
 
@@ -1120,14 +1134,6 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data,
                           (unichar **) NULL, &verlen, &vallen, &type, &off))
     return NULL;
 
-  /* PR 17512: The verlen field does not include padding length.  */
-  if (verlen > length)
-    {
-      non_fatal (_("version length %lu greater than resource length %lu"),
-                (unsigned long) verlen, (unsigned long) length);
-      return NULL;
-    }
-
   if (type != 0)
     {
       non_fatal (_("unexpected version type %d"), (int) type);
@@ -1311,7 +1317,7 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data,
                  if (stverlen < sverlen)
                    {
                      non_fatal (_("unexpected version string length %ld < %ld"),
-                                (long) verlen, (long) sverlen);
+                                (long) stverlen, (long) sverlen);
                      return NULL;
                    }
                  stverlen -= sverlen;