aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2025-08-17 21:34:17 +0930
committerAlan Modra <amodra@gmail.com>2025-08-17 22:32:43 +0930
commita5858e81363051a818ea163d52f62d8251097d11 (patch)
treea8b155e91b3baadb21905ef94dcc563de848fffd
parentddc09604ad38dd325c1cf7f5d9ce37ba4c28464e (diff)
downloadbinutils-a5858e81363051a818ea163d52f62d8251097d11.zip
binutils-a5858e81363051a818ea163d52f62d8251097d11.tar.gz
binutils-a5858e81363051a818ea163d52f62d8251097d11.tar.bz2
Sanity check windows resource version len
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.
-rw-r--r--binutils/resbin.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/binutils/resbin.c b/binutils/resbin.c
index fa77cd4..02905b9 100644
--- a/binutils/resbin.c
+++ b/binutils/resbin.c
@@ -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;