Fixes for invalid memory accesses triggered by running windres on corrupt binaries.
PR binutils/17512 * rcparse.y: Add checks to avoid integer divide by zero. * rescoff.c (read_coff_rsrc): Add check on the size of the resource section. (read_coff_res_dir): Add check on the nesting level. Check for resource names overrunning the buffer. * resrc.c (write_rc_messagetable): Update formatting. Add check of 'elen' being zero.
This commit is contained in:
parent
877a8638ba
commit
0897ec1581
4 changed files with 89 additions and 52 deletions
|
@ -142,8 +142,14 @@ 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);
|
||||
/* 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;
|
||||
|
@ -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 >= (bfd_byte *) ere || ers + j * 2 + 4 >= (bfd_byte *) ere)
|
||||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue