mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 14:49:38 +08:00
Fix address violation problems when parsing corrupt ELF binaries.
PR 21916 * elf-attrs.c (_bfd_elf_parse_attributes): Complain about very small section lengths. * elf.c (_bfd_elf_setup_sections): Skip empty entries in the group table. (elfcore_grok_freebsd_prstatus): Add checks to make sure that there is enough data present in the note.
This commit is contained in:
@ -1,3 +1,13 @@
|
||||
2017-08-08 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 21916
|
||||
* elf-attrs.c (_bfd_elf_parse_attributes): Complain about very
|
||||
small section lengths.
|
||||
* elf.c (_bfd_elf_setup_sections): Skip empty entries in the group
|
||||
table.
|
||||
(elfcore_grok_freebsd_prstatus): Add checks to make sure that
|
||||
there is enough data present in the note.
|
||||
|
||||
2017-08-08 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 21017
|
||||
|
@ -468,6 +468,12 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
|
||||
if (section_len > len)
|
||||
section_len = len;
|
||||
len -= section_len;
|
||||
if (section_len <= 4)
|
||||
{
|
||||
_bfd_error_handler (_("%B: error: attribute section length too small: %ld"),
|
||||
abfd, section_len);
|
||||
break;
|
||||
}
|
||||
section_len -= 4;
|
||||
namelen = strnlen ((char *) p, section_len) + 1;
|
||||
if (namelen == 0 || namelen >= section_len)
|
||||
|
47
bfd/elf.c
47
bfd/elf.c
@ -896,7 +896,12 @@ _bfd_elf_setup_sections (bfd *abfd)
|
||||
n_elt = shdr->sh_size / 4;
|
||||
|
||||
while (--n_elt != 0)
|
||||
if ((++idx)->shdr->bfd_section)
|
||||
{
|
||||
++ idx;
|
||||
|
||||
if (idx->shdr == NULL)
|
||||
continue;
|
||||
else if (idx->shdr->bfd_section)
|
||||
elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
|
||||
else if (idx->shdr->sh_type == SHT_RELA
|
||||
|| idx->shdr->sh_type == SHT_REL)
|
||||
@ -922,6 +927,8 @@ _bfd_elf_setup_sections (bfd *abfd)
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -9883,39 +9890,45 @@ elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note)
|
||||
{
|
||||
size_t offset;
|
||||
size_t size;
|
||||
size_t min_size;
|
||||
|
||||
/* Check for version 1 in pr_version. */
|
||||
if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
|
||||
return FALSE;
|
||||
offset = 4;
|
||||
|
||||
/* Skip over pr_statussz. */
|
||||
/* Compute offset of pr_getregsz, skipping over pr_statussz.
|
||||
Also compute minimum size of this note. */
|
||||
switch (elf_elfheader (abfd)->e_ident[EI_CLASS])
|
||||
{
|
||||
case ELFCLASS32:
|
||||
offset += 4;
|
||||
offset = 4 + 4;
|
||||
min_size = offset + (4 * 2) + 4 + 4 + 4;
|
||||
break;
|
||||
|
||||
case ELFCLASS64:
|
||||
offset += 4; /* Padding before pr_statussz. */
|
||||
offset += 8;
|
||||
offset = 4 + 4 + 8; /* Includes padding before pr_statussz. */
|
||||
min_size = offset + (8 * 2) + 4 + 4 + 4 + 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Extract size of pr_reg from pr_gregsetsz. */
|
||||
if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32)
|
||||
size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
|
||||
else
|
||||
size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset);
|
||||
if (note->descsz < min_size)
|
||||
return FALSE;
|
||||
|
||||
/* Check for version 1 in pr_version. */
|
||||
if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
|
||||
return FALSE;
|
||||
|
||||
/* Extract size of pr_reg from pr_gregsetsz. */
|
||||
/* Skip over pr_gregsetsz and pr_fpregsetsz. */
|
||||
if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32)
|
||||
{
|
||||
size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
|
||||
offset += 4 * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset);
|
||||
offset += 8 * 2;
|
||||
}
|
||||
|
||||
/* Skip over pr_osreldate. */
|
||||
offset += 4;
|
||||
@ -9935,6 +9948,10 @@ elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note)
|
||||
if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
|
||||
offset += 4;
|
||||
|
||||
/* Make sure that there is enough data remaining in the note. */
|
||||
if ((note->descsz - offset) < size)
|
||||
return FALSE;
|
||||
|
||||
/* Make a ".reg/999" section and a ".reg" section. */
|
||||
return _bfd_elfcore_make_pseudosection (abfd, ".reg",
|
||||
size, note->descpos + offset);
|
||||
|
Reference in New Issue
Block a user