diff options
author | Alan Modra <amodra@gmail.com> | 2025-08-17 21:34:17 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2025-08-17 22:32:43 +0930 |
commit | a5858e81363051a818ea163d52f62d8251097d11 (patch) | |
tree | a8b155e91b3baadb21905ef94dcc563de848fffd | |
parent | ddc09604ad38dd325c1cf7f5d9ce37ba4c28464e (diff) | |
download | binutils-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.c | 26 |
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; |