Fix memory access problems discovered when running some binary tools on corrupt files.

PR binutils/18758
	* elf.c (_bfd_elf_setup_sections): Add checks for corrupt section
	group information.
	* peicode.h (pe_ILF_make_a_section): Ensure alignment of the
	used_by_bfd pointer.
	(pe_ILF_build_a_bfd): Ensure alignment of vars.data pointer.
This commit is contained in:
Nick Clifton 2015-08-11 11:57:09 +01:00
parent 64140f86ab
commit 4b0e8a5f80
3 changed files with 56 additions and 2 deletions

View File

@ -1,3 +1,12 @@
2015-08-11 Nick Clifton <nickc@redhat.com>
PR binutils/18758
* elf.c (_bfd_elf_setup_sections): Add checks for corrupt section
group information.
* peicode.h (pe_ILF_make_a_section): Ensure alignment of the
used_by_bfd pointer.
(pe_ILF_build_a_bfd): Ensure alignment of vars.data pointer.
2015-08-11 H.J. Lu <hongjiu.lu@intel.com>
* elf.c (_bfd_elf_copy_private_bfd_data): Fix a typo.

View File

@ -817,9 +817,22 @@ _bfd_elf_setup_sections (bfd *abfd)
for (i = 0; i < num_group; i++)
{
Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
unsigned int n_elt = shdr->sh_size / 4;
Elf_Internal_Group *idx;
unsigned int n_elt;
/* PR binutils/18758: Beware of corrupt binaries with invalid group data. */
if (shdr == NULL || shdr->bfd_section == NULL || shdr->contents == NULL)
{
(*_bfd_error_handler)
(_("%B: section group entry number %u is corrupt"),
abfd, i);
result = FALSE;
continue;
}
idx = (Elf_Internal_Group *) shdr->contents;
n_elt = shdr->sh_size / 4;
while (--n_elt != 0)
if ((++idx)->shdr->bfd_section)
elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;

View File

@ -631,6 +631,20 @@ pe_ILF_make_a_section (pe_ILF_vars * vars,
if (size & 1)
vars->data --;
# if (GCC_VERSION >= 3000)
/* PR 18758: See note in pe_ILF_buid_a_bfd. We must make sure that we
preserve host alignment requirements. We test 'size' rather than
vars.data as we cannot perform binary arithmetic on pointers. We assume
that vars.data was sufficiently aligned upon entry to this function.
The BFD_ASSERTs in this functions will warn us if we run out of room,
but we should already have enough padding built in to ILF_DATA_SIZE. */
{
unsigned int alignment = __alignof__ (struct coff_section_tdata);
if (size & (alignment - 1))
vars->data += alignment - (size & (alignment - 1));
}
#endif
/* Create a coff_section_tdata structure for our use. */
sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
vars->data += sizeof (struct coff_section_tdata);
@ -836,6 +850,24 @@ pe_ILF_build_a_bfd (bfd * abfd,
/* The remaining space in bim->buffer is used
by the pe_ILF_make_a_section() function. */
# if (GCC_VERSION >= 3000)
/* PR 18758: Make sure that the data area is sufficiently aligned for
pointers on the host. __alignof__ is a gcc extension, hence the test
above. For other compilers we will have to assume that the alignment is
unimportant, or else extra code can be added here and in
pe_ILF_make_a_section.
Note - we cannot test 'ptr' directly as it is illegal to perform binary
arithmetic on pointers, but we know that the strings section is the only
one that might end on an unaligned boundary. */
{
unsigned int alignment = __alignof__ (char *);
if (SIZEOF_ILF_STRINGS & (alignment - 1))
ptr += alignment - (SIZEOF_ILF_STRINGS & (alignment - 1));
}
#endif
vars.data = ptr;
vars.abfd = abfd;
vars.sec_index = 0;