Fix seg-fault reading a corrupt ELF binary.
authorNick Clifton <nickc@redhat.com>
Wed, 21 Jun 2017 09:36:58 +0000 (10:36 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 21 Jun 2017 09:36:58 +0000 (10:36 +0100)
PR binutils/21640
* elf.c (setup_group): Zero the group section pointer list after
allocation so that loops can be caught.  Check for NULL pointers
when processing a group list.

bfd/ChangeLog
bfd/elf.c

index 770fdf16a283ce5b5e87dcf006f3d839e215c502..9bc63e1d6c5c02b06c13437a057e31321e5449e0 100644 (file)
@@ -1,3 +1,10 @@
+2017-06-21  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/21640
+       * elf.c (setup_group): Zero the group section pointer list after
+       allocation so that loops can be caught.  Check for NULL pointers
+       when processing a group list.
+
 2017-06-19  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/21626
index fb106e9449bc990f4c8644908c396e0fc3ed65c0..5f37e7f79c764efc3f80b8a644f65ecfe9df4206 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -613,6 +613,7 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
        {
          num_group = (unsigned) -1;
          elf_tdata (abfd)->num_group = num_group;
+         elf_tdata (abfd)->group_sect_ptr = NULL;
        }
       else
        {
@@ -625,8 +626,9 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
               bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
          if (elf_tdata (abfd)->group_sect_ptr == NULL)
            return FALSE;
-
+         memset (elf_tdata (abfd)->group_sect_ptr, 0, num_group * sizeof (Elf_Internal_Shdr *));
          num_group = 0;
+
          for (i = 0; i < shnum; i++)
            {
              Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
@@ -739,8 +741,14 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
       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;
+
+         if (shdr == NULL)
+           continue;
+
+         idx = (Elf_Internal_Group *) shdr->contents;
+         n_elt = shdr->sh_size / 4;
 
          /* Look through this group's sections to see if current
             section is a member.  */