From: Alan Modra Date: Sun, 17 Aug 2025 12:04:17 +0000 (+0930) Subject: Sanity check windows resource version len X-Git-Tag: gdb-17-branchpoint~273 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5858e81363051a818ea163d52f62d8251097d11;p=thirdparty%2Fbinutils-gdb.git 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. --- diff --git a/binutils/resbin.c b/binutils/resbin.c index fa77cd43d23..02905b9c9de 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;