Fix memory corruption when assembling an i386 darwin source file.
authorNick Clifton <nickc@redhat.com>
Thu, 10 Aug 2017 10:51:42 +0000 (11:51 +0100)
committerNick Clifton <nickc@redhat.com>
Thu, 10 Aug 2017 10:51:42 +0000 (11:51 +0100)
PR gas/21939
* config/obj-macho.c (obj_mach_o_set_indirect_symbols): Increase
size of indirect_syms array so that it is large enough to hold
every symbol if necessary.

gas/ChangeLog
gas/config/obj-macho.c

index 3edb1795a67d85354be148cfef49efc54be4f51f..adeb38bb27abd06cd1301354daf42216ba080a92 100644 (file)
@@ -1,3 +1,10 @@
+2017-08-10  Nick Clifton  <nickc@redhat.com>
+
+       PR gas/21939
+       * config/obj-macho.c (obj_mach_o_set_indirect_symbols): Increase
+       size of indirect_syms array so that it is large enough to hold
+       every symbol if necessary.
+
 2017-08-09  Jiong Wang  <jiong.wang@arm.com>
 
        * config/tc-arm.c (do_crc32_1): Remove warning on REG_SP for thumb_mode.
index 28867bd3eebf049acffa62a1557112206670ae9b..8cc9581cbbef2d7738ce73fa9936a3e56f990412 100644 (file)
@@ -1808,15 +1808,21 @@ obj_mach_o_set_indirect_symbols (bfd *abfd, asection *sec,
            {
              unsigned n;
              bfd_mach_o_asymbol *sym;
+
+             /* FIXME: It seems that there can be more indirect symbols
+                than is computed by the loop above.  So be paranoid and
+                allocate enough space for every symbol to be indirect.
+                See PR 21939 for an example of where this is needed.  */
+             if (nactual < bfd_get_symcount (abfd))
+               nactual = bfd_get_symcount (abfd);
+
              ms->indirect_syms =
                        bfd_zalloc (abfd,
                                    nactual * sizeof (bfd_mach_o_asymbol *));
 
              if (ms->indirect_syms == NULL)
-               {
-                 as_fatal (_("internal error: failed to allocate %d indirect"
-                             "symbol pointers"), nactual);
-               }
+               as_fatal (_("internal error: failed to allocate %d indirect"
+                           "symbol pointers"), nactual);
 
              for (isym = list, n = 0; isym != NULL; isym = isym->next, n++)
                {
@@ -1827,7 +1833,11 @@ obj_mach_o_set_indirect_symbols (bfd *abfd, asection *sec,
 
                     Absolute symbols are handled specially.  */
                  if (sym->symbol.section == bfd_abs_section_ptr)
-                   ms->indirect_syms[n] = sym;
+                   {
+                     if (n >= nactual)
+                       as_fatal (_("internal error: more indirect mach-o symbols than expected"));
+                     ms->indirect_syms[n] = sym;
+                   }
                  else if (S_IS_LOCAL (isym->sym) && ! lazy)
                    ;
                  else
@@ -1847,6 +1857,8 @@ obj_mach_o_set_indirect_symbols (bfd *abfd, asection *sec,
                              && ! (sym->n_type & BFD_MACH_O_N_PEXT)
                              && (sym->n_type & BFD_MACH_O_N_EXT))
                            sym->n_desc |= lazy;
+                         if (n >= nactual)
+                           as_fatal (_("internal error: more indirect mach-o symbols than expected"));
                          ms->indirect_syms[n] = sym;
                        }
                    }