aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2016-12-05 14:32:30 +0000
committerNick Clifton <nickc@redhat.com>2016-12-05 14:32:30 +0000
commite2996cc315d6ea242e1a954dc20246485ccc8512 (patch)
tree69ac5d7dd89cadd5802ada7aca457b5435ae2294 /bfd
parentc28eeff2eabbba2246799470f3713716fa629680 (diff)
downloadgdb-e2996cc315d6ea242e1a954dc20246485ccc8512.zip
gdb-e2996cc315d6ea242e1a954dc20246485ccc8512.tar.gz
gdb-e2996cc315d6ea242e1a954dc20246485ccc8512.tar.bz2
Fix seg-fault running strip on a corrupt binary.
PR binutils/20921 * aoutx.h (squirt_out_relocs): Check for and report any relocs that could not be recognised.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog4
-rw-r--r--bfd/aoutx.h27
2 files changed, 27 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9632eac..7388bb2 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index 4de02e2..43e5f8d 100644
--- a/bfd/aoutx.h
+++ b/bfd/aoutx.h
@@ -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)