PR23199, Invalid SHT_GROUP entry leads to group confusion
authorAlan Modra <amodra@gmail.com>
Fri, 18 May 2018 07:39:45 +0000 (17:09 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 18 May 2018 09:02:35 +0000 (18:32 +0930)
This patch prevents elf_next_in_group list pointer confusion when
SHT_GROUP sections specify other SHT_GROUP sections in their list of
group sections.

PR 23199
* elf.c (setup_group): Formatting.  Check that SHT_GROUP entries
don't point at other SHT_GROUP sections.  Set shdr corresponding
to invalid entry, to NULL rather than section 0.  Identify
SHT_GROUP section index when reporting an error.  Cope with NULL
shdr pointer.

bfd/ChangeLog
bfd/elf.c

index 3b5774a2b4c58a09614f960bf27f0c4ea0013a0b..f0ea6f940b1d225fb696e4a9a55932d5c7ed9098 100644 (file)
@@ -1,3 +1,12 @@
+2018-05-18  Alan Modra  <amodra@gmail.com>
+
+       PR 23199
+       * elf.c (setup_group): Formatting.  Check that SHT_GROUP entries
+       don't point at other SHT_GROUP sections.  Set shdr corresponding
+       to invalid entry, to NULL rather than section 0.  Identify
+       SHT_GROUP section index when reporting an error.  Cope with NULL
+       shdr pointer.
+
 2018-05-18  Alan Modra  <amodra@gmail.com>
 
        * libbfd-in.h (ATTRIBUTE_HIDDEN): Define and use throughout.
index 024b6cd86af5c9ce52f022696afaaae56f61c078..47d046fa8346d2b47d32c94a12f700cbb7a8a461 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -628,7 +628,8 @@ 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 *));
+         memset (elf_tdata (abfd)->group_sect_ptr, 0,
+                 num_group * sizeof (Elf_Internal_Shdr *));
          num_group = 0;
 
          for (i = 0; i < shnum; i++)
@@ -709,13 +710,16 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
                              |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
                          break;
                        }
-                     if (idx >= shnum)
+                     if (idx < shnum)
+                       dest->shdr = elf_elfsections (abfd)[idx];
+                     if (idx >= shnum
+                         || dest->shdr->sh_type == SHT_GROUP)
                        {
                          _bfd_error_handler
-                           (_("%pB: invalid SHT_GROUP entry"), abfd);
-                         idx = 0;
+                           (_("%pB: invalid entry in SHT_GROUP section [%u]"),
+                              abfd, i);
+                         dest->shdr = NULL;
                        }
-                     dest->shdr = elf_elfsections (abfd)[idx];
                    }
                }
            }
@@ -781,7 +785,8 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
                idx = (Elf_Internal_Group *) shdr->contents;
                n_elt = shdr->sh_size / 4;
                while (--n_elt != 0)
-                 if ((s = (++idx)->shdr->bfd_section) != NULL
+                 if ((++idx)->shdr != NULL
+                     && (s = idx->shdr->bfd_section) != NULL
                      && elf_next_in_group (s) != NULL)
                    break;
                if (n_elt != 0)