Fix seg-fault running strip on a corrupt binary.
authorNick Clifton <nickc@redhat.com>
Mon, 5 Dec 2016 14:32:30 +0000 (14:32 +0000)
committerNick Clifton <nickc@redhat.com>
Mon, 5 Dec 2016 14:32:30 +0000 (14:32 +0000)
PR binutils/20921
* aoutx.h (squirt_out_relocs): Check for and report any relocs
that could not be recognised.

bfd/ChangeLog
bfd/aoutx.h

index 9632eac61ea607dd20082abdf7ae0bf6849c279a..7388bb289a9f383974086c3901c5561661aa3fac 100644 (file)
@@ -5,6 +5,10 @@
 
 2016-12-05  Nick Clifton  <nickc@redhat.com>
 
+       PR binutils/20921
+       * aoutx.h (squirt_out_relocs): Check for and report any relocs
+       that could not be recognised.
+
        PR binutils/20922
        * elf.c (find_link): Check for null headers before attempting to
        match them.
index 4de02e261984efa0d111c3a802f14f87aa14322f..43e5f8d218dec8e651b1bbde8ee882c1bc2027a6 100644 (file)
@@ -1955,6 +1955,7 @@ NAME (aout, swap_std_reloc_out) (bfd *abfd,
 
   PUT_WORD (abfd, g->address, natptr->r_address);
 
+  BFD_ASSERT (g->howto != NULL);
   r_length = g->howto->size ;  /* Size as a power of two.  */
   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC?  */
   /* XXX This relies on relocs coming from a.out files.  */
@@ -2393,16 +2394,34 @@ NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
       for (natptr = native;
           count != 0;
           --count, natptr += each_size, ++generic)
-       MY_swap_ext_reloc_out (abfd, *generic,
-                              (struct reloc_ext_external *) natptr);
+       {
+         if ((*generic)->howto == NULL)
+           {
+             bfd_set_error (bfd_error_invalid_operation);
+             _bfd_error_handler (_("%B: attempt to write out unknown reloc type"), abfd);
+             return FALSE;
+           }
+         MY_swap_ext_reloc_out (abfd, *generic,
+                                (struct reloc_ext_external *) natptr);
+       }
     }
   else
     {
       for (natptr = native;
           count != 0;
           --count, natptr += each_size, ++generic)
-       MY_swap_std_reloc_out (abfd, *generic,
-                              (struct reloc_std_external *) natptr);
+       {
+         /* PR 20921: If the howto field has not been initialised then skip
+            this reloc.  */
+         if ((*generic)->howto == NULL)
+           {
+             bfd_set_error (bfd_error_invalid_operation);
+             _bfd_error_handler (_("%B: attempt to write out unknown reloc type"), abfd);
+             return FALSE;
+           }
+         MY_swap_std_reloc_out (abfd, *generic,
+                                (struct reloc_std_external *) natptr);
+       }
     }
 
   if (bfd_bwrite ((void *) native, natsize, abfd) != natsize)