aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-08-11 11:57:09 +0100
committerNick Clifton <nickc@redhat.com>2015-08-11 11:57:09 +0100
commit4b0e8a5f80441fad8eddaf68e7af70bd6991aa37 (patch)
treeff5f7482114d200ce52b6094c721df98dc2478ad
parent64140f86ab732f9ed87beccab07c32befaf9ca52 (diff)
downloadgdb-4b0e8a5f80441fad8eddaf68e7af70bd6991aa37.zip
gdb-4b0e8a5f80441fad8eddaf68e7af70bd6991aa37.tar.gz
gdb-4b0e8a5f80441fad8eddaf68e7af70bd6991aa37.tar.bz2
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.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf.c17
-rw-r--r--bfd/peicode.h32
3 files changed, 56 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 91d41d3..b3b4239 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf.c b/bfd/elf.c
index 15de37b..7ae2e34 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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;
diff --git a/bfd/peicode.h b/bfd/peicode.h
index 06bcaa9..668e742 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -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;