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:
Alan Modra 2023-04-12 11:00:42 +09:30
parent 32011d23a8
commit 93c6e8c3c1
5 changed files with 14 additions and 11 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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) +