mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 11:39:26 +08:00
PR26011, excessive memory allocation with fuzzed reloc sections
Check sizes early, before users of slurp_relocs allocate buffers for the swapped in relocs. PR 26011 * elf.c (_bfd_elf_get_reloc_upper_bound): Sanity check reloc section size against file size. (_bfd_elf_get_dynamic_reloc_upper_bound): Likewise.
This commit is contained in:
@ -1,3 +1,10 @@
|
||||
2020-05-20 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 26011
|
||||
* elf.c (_bfd_elf_get_reloc_upper_bound): Sanity check reloc
|
||||
section size against file size.
|
||||
(_bfd_elf_get_dynamic_reloc_upper_bound): Likewise.
|
||||
|
||||
2020-05-19 Gunther Nikl <gnikl@justmail.de>
|
||||
|
||||
PR 26005
|
||||
|
37
bfd/elf.c
37
bfd/elf.c
@ -8508,9 +8508,23 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
|
||||
}
|
||||
|
||||
long
|
||||
_bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
sec_ptr asect)
|
||||
_bfd_elf_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
|
||||
{
|
||||
if (asect->reloc_count != 0)
|
||||
{
|
||||
/* Sanity check reloc section size. */
|
||||
struct bfd_elf_section_data *d = elf_section_data (asect);
|
||||
Elf_Internal_Shdr *rel_hdr = &d->this_hdr;
|
||||
bfd_size_type ext_rel_size = rel_hdr->sh_size;
|
||||
ufile_ptr filesize = bfd_get_file_size (abfd);
|
||||
|
||||
if (filesize != 0 && ext_rel_size > filesize)
|
||||
{
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if SIZEOF_LONG == SIZEOF_INT
|
||||
if (asect->reloc_count >= LONG_MAX / sizeof (arelent *))
|
||||
{
|
||||
@ -8576,7 +8590,7 @@ _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
|
||||
long
|
||||
_bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
|
||||
{
|
||||
bfd_size_type count;
|
||||
bfd_size_type count, ext_rel_size;
|
||||
asection *s;
|
||||
|
||||
if (elf_dynsymtab (abfd) == 0)
|
||||
@ -8586,11 +8600,18 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
|
||||
}
|
||||
|
||||
count = 1;
|
||||
ext_rel_size = 0;
|
||||
for (s = abfd->sections; s != NULL; s = s->next)
|
||||
if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
|
||||
&& (elf_section_data (s)->this_hdr.sh_type == SHT_REL
|
||||
|| elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
|
||||
{
|
||||
ext_rel_size += s->size;
|
||||
if (ext_rel_size < s->size)
|
||||
{
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
return -1;
|
||||
}
|
||||
count += s->size / elf_section_data (s)->this_hdr.sh_entsize;
|
||||
if (count > LONG_MAX / sizeof (arelent *))
|
||||
{
|
||||
@ -8598,6 +8619,16 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (count > 1)
|
||||
{
|
||||
/* Sanity check reloc section sizes. */
|
||||
ufile_ptr filesize = bfd_get_file_size (abfd);
|
||||
if (filesize != 0 && ext_rel_size > filesize)
|
||||
{
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return count * sizeof (arelent *);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user