mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
PR30326, uninitialised value in objdump compare_relocs
This is a fuzzing PR, with a testcase involving a SHF_ALLOC and SHF_COMPRESSED SHT_RELA section, ie. a compressed dynamic reloc section. BFD doesn't handle compressed relocation sections, with most of the code reading relocs using sh_size (often no bfd section is created) but in the case of SHF_ALLOC dynamic relocs we had some code using the bfd section size. This led to a mismatch, sh_size is compressed, size is uncompressed, and from that some uninitialised memory. Consistently using sh_size is enough to fix this PR, but I've also added tests to exclude SHF_COMPRESSED reloc sections from consideration. PR 30362 * elf.c (bfd_section_from_shdr): Exclude reloc sections with SHF_COMPRESSED flag from normal reloc processing. (_bfd_elf_get_dynamic_reloc_upper_bound): Similarly exclude SHF_COMPRESSED sections from consideration. Use sh_size when sizing to match slurp_relocs. (_bfd_elf_canonicalize_dynamic_reloc): Likewise. (_bfd_elf_get_synthetic_symtab): Use NUM_SHDR_ENTRIES to size plt relocs. * elf32-arm.c (elf32_arm_get_synthetic_symtab): Likewise. * elf32-ppc.c (ppc_elf_get_synthetic_symtab): Likewise. * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Likewise. * elfxx-mips.c (_bfd_mips_elf_get_synthetic_symtab): Likewise.
This commit is contained in:
parent
32011d23a8
commit
93c6e8c3c1
17
bfd/elf.c
17
bfd/elf.c
@ -2381,6 +2381,7 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
|
||||
its sh_link points to the null section. */
|
||||
if (((abfd->flags & (DYNAMIC | EXEC_P)) != 0
|
||||
&& (hdr->sh_flags & SHF_ALLOC) != 0)
|
||||
|| (hdr->sh_flags & SHF_COMPRESSED) != 0
|
||||
|| hdr->sh_type == SHT_RELR
|
||||
|| hdr->sh_link == SHN_UNDEF
|
||||
|| hdr->sh_link != elf_onesymtab (abfd)
|
||||
@ -8728,15 +8729,16 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
|
||||
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))
|
||||
|| elf_section_data (s)->this_hdr.sh_type == SHT_RELA)
|
||||
&& (elf_section_data (s)->this_hdr.sh_flags & SHF_COMPRESSED) == 0)
|
||||
{
|
||||
ext_rel_size += s->size;
|
||||
if (ext_rel_size < s->size)
|
||||
ext_rel_size += elf_section_data (s)->this_hdr.sh_size;
|
||||
if (ext_rel_size < elf_section_data (s)->this_hdr.sh_size)
|
||||
{
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
return -1;
|
||||
}
|
||||
count += s->size / elf_section_data (s)->this_hdr.sh_entsize;
|
||||
count += NUM_SHDR_ENTRIES (&elf_section_data (s)->this_hdr);
|
||||
if (count > LONG_MAX / sizeof (arelent *))
|
||||
{
|
||||
bfd_set_error (bfd_error_file_too_big);
|
||||
@ -8785,14 +8787,15 @@ _bfd_elf_canonicalize_dynamic_reloc (bfd *abfd,
|
||||
{
|
||||
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))
|
||||
|| elf_section_data (s)->this_hdr.sh_type == SHT_RELA)
|
||||
&& (elf_section_data (s)->this_hdr.sh_flags & SHF_COMPRESSED) == 0)
|
||||
{
|
||||
arelent *p;
|
||||
long count, i;
|
||||
|
||||
if (! (*slurp_relocs) (abfd, s, syms, true))
|
||||
return -1;
|
||||
count = s->size / elf_section_data (s)->this_hdr.sh_entsize;
|
||||
count = NUM_SHDR_ENTRIES (&elf_section_data (s)->this_hdr);
|
||||
p = s->relocation;
|
||||
for (i = 0; i < count; i++)
|
||||
*storage++ = p++;
|
||||
@ -12936,7 +12939,7 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
|
||||
if (! (*slurp_relocs) (abfd, relplt, dynsyms, true))
|
||||
return -1;
|
||||
|
||||
count = relplt->size / hdr->sh_entsize;
|
||||
count = NUM_SHDR_ENTRIES (hdr);
|
||||
size = count * sizeof (asymbol);
|
||||
p = relplt->relocation;
|
||||
for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
|
||||
|
@ -20067,7 +20067,7 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
|
||||
plt->flags |= SEC_IN_MEMORY;
|
||||
}
|
||||
|
||||
count = relplt->size / hdr->sh_entsize;
|
||||
count = NUM_SHDR_ENTRIES (hdr);
|
||||
size = count * sizeof (asymbol);
|
||||
p = relplt->relocation;
|
||||
for (i = 0; i < count; i++, p += elf32_arm_size_info.int_rels_per_ext_rel)
|
||||
|
@ -1920,7 +1920,7 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
|
||||
}
|
||||
}
|
||||
|
||||
count = relplt->size / sizeof (Elf32_External_Rela);
|
||||
count = NUM_SHDR_ENTRIES (&elf_section_data (relplt)->this_hdr);
|
||||
/* If the stubs are those for -shared/-pie then we might have
|
||||
multiple stubs for each plt entry. If that is the case then
|
||||
there is no way to associate stubs with their plt entries short
|
||||
|
@ -2576,7 +2576,7 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
||||
if (!(*slurp_relocs) (abfd, relplt, dyn_syms, true))
|
||||
goto free_contents_and_exit_err;
|
||||
|
||||
plt_count = relplt->size / sizeof (Elf64_External_Rela);
|
||||
plt_count = NUM_SHDR_ENTRIES (&elf_section_data (relplt)->this_hdr);
|
||||
size += plt_count * sizeof (asymbol);
|
||||
|
||||
p = relplt->relocation;
|
||||
|
@ -16595,7 +16595,7 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
|
||||
/* Calculating the exact amount of space required for symbols would
|
||||
require two passes over the PLT, so just pessimise assuming two
|
||||
PLT slots per relocation. */
|
||||
count = relplt->size / hdr->sh_entsize;
|
||||
count = NUM_SHDR_ENTRIES (hdr);
|
||||
counti = count * bed->s->int_rels_per_ext_rel;
|
||||
size = 2 * count * sizeof (asymbol);
|
||||
size += count * (sizeof (mipssuffix) +
|
||||
|
Loading…
Reference in New Issue
Block a user