X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Frescoff.c;h=c23a808e8207e90cbfde4b883ddd897d1c397afd;hb=b6fb30eda72b7fc3a6214ed2787f80971f66810d;hp=607c8231b7d4aa30d379c72e898375402ed5d553;hpb=4b95cf5c0c75d6efc1b2f96af72317aecca079f1;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/rescoff.c b/binutils/rescoff.c index 607c8231b7..c23a808e82 100644 --- a/binutils/rescoff.c +++ b/binutils/rescoff.c @@ -1,5 +1,5 @@ /* rescoff.c -- read and write resources in Windows COFF files. - Copyright (C) 1997-2014 Free Software Foundation, Inc. + Copyright (C) 1997-2020 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. Rewritten by Kai Tietz, Onevision. @@ -141,16 +141,22 @@ read_coff_rsrc (const char *filename, const char *target) } set_windres_bfd (&wrbfd, abfd, sec, WR_KIND_BFD); - size = bfd_section_size (abfd, sec); - data = (bfd_byte *) res_alloc (size); + size = bfd_section_size (sec); + /* PR 17512: file: 1b25ba5d + The call to get_file_size here may be expensive + but there is no other way to determine if the section size + is reasonable. */ + if (size > (bfd_size_type) get_file_size (filename)) + fatal (_("%s: .rsrc section is bigger than the file!"), filename); + data = (bfd_byte *) res_alloc (size); get_windres_bfd_content (&wrbfd, data, 0, size); flaginfo.filename = filename; flaginfo.data = data; flaginfo.data_end = data + size; - flaginfo.secaddr = (bfd_get_section_vma (abfd, sec) - - pe_data (abfd)->pe_opthdr.ImageBase); + flaginfo.secaddr = (bfd_section_vma (sec) + - pe_data (abfd)->pe_opthdr.ImageBase); /* Now just read in the top level resource directory. Note that we don't free data, since we create resource entries that point into @@ -158,7 +164,7 @@ read_coff_rsrc (const char *filename, const char *target) this will have to be cleaned up. */ ret = read_coff_res_dir (&wrbfd, data, &flaginfo, (const rc_res_id *) NULL, 0); - + bfd_close (abfd); return ret; @@ -185,6 +191,13 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data, rc_res_entry **pp; const struct extern_res_entry *ere; + /* PR 17512: file: 09d80f53. + Whilst in theory resources can nest to any level, in practice + Microsoft only defines 3 levels. Corrupt files however might + claim to use more. */ + if (level > 4) + overrun (flaginfo, _("Resources nest too deep")); + if ((size_t) (flaginfo->data_end - data) < sizeof (struct extern_res_directory)) overrun (flaginfo, _("directory")); @@ -234,7 +247,12 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data, re->id.u.n.length = length; re->id.u.n.name = (unichar *) res_alloc (length * sizeof (unichar)); for (j = 0; j < length; j++) - re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2); + { + /* PR 17512: file: 05dc4a16. */ + 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); + } if (level == 0) type = &re->id; @@ -529,7 +547,7 @@ write_coff_file (const char *filename, const char *target, + cwi.dataentsize + cwi.resources.length); - if (! bfd_set_section_size (abfd, sec, length)) + if (!bfd_set_section_size (sec, length)) bfd_fatal ("bfd_set_section_size"); bfd_set_reloc (abfd, sec, cwi.relocs, cwi.reloc_count);