diff options
author | Nick Clifton <nickc@redhat.com> | 2016-12-05 14:32:30 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2016-12-05 14:32:30 +0000 |
commit | e2996cc315d6ea242e1a954dc20246485ccc8512 (patch) | |
tree | 69ac5d7dd89cadd5802ada7aca457b5435ae2294 | |
parent | c28eeff2eabbba2246799470f3713716fa629680 (diff) | |
download | gdb-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.
-rw-r--r-- | bfd/ChangeLog | 4 | ||||
-rw-r--r-- | bfd/aoutx.h | 27 |
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) |