From 4931146e91c3c8208f1e0b8462b8f33e70da506a Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 28 Jul 2016 15:37:16 +0100 Subject: [PATCH] Fix decoding of Windows resources. 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 | 8 ++++++++ binutils/resbin.c | 16 ++++++++++++---- binutils/rescoff.c | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 43ed236cc7..358b5a4930 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,11 @@ +2016-07-28 Nick Clifton + + 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 * configure: Regenerated. diff --git a/binutils/resbin.c b/binutils/resbin.c index 03d3010d19..9ca540853d 100644 --- a/binutils/resbin.c +++ b/binutils/resbin.c @@ -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; diff --git a/binutils/rescoff.c b/binutils/rescoff.c index 74a61a7be5..9151eab93f 100644 --- a/binutils/rescoff.c +++ b/binutils/rescoff.c @@ -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); }