aboutsummaryrefslogtreecommitdiff
path: root/bfd/reloc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-10-13 22:03:02 +1030
committerAlan Modra <amodra@gmail.com>2018-10-13 23:54:33 +1030
commit0930cb3021b8078b34cf216e79eb8608d017864f (patch)
treec5368b36cb84da2d40b57d14e28432773ef161c9 /bfd/reloc.c
parent2bf2bf23da5237f465fdbb759657aeb7825a08a3 (diff)
downloadfsf-binutils-gdb-0930cb3021b8078b34cf216e79eb8608d017864f.zip
fsf-binutils-gdb-0930cb3021b8078b34cf216e79eb8608d017864f.tar.gz
fsf-binutils-gdb-0930cb3021b8078b34cf216e79eb8608d017864f.tar.bz2
_bfd_clear_contents bounds checking
This PR shows a fuzzed binary triggering a segfault via a bad relocation in .debug_line. It turns out that unlike normal relocations applied to a section, the linker applies those with symbols from discarded sections via _bfd_clear_contents without checking that the relocation is within the section bounds. The same thing now happens when reading debug sections since commit a4cd947aca23, the PR23425 fix. PR 23770 PR 23425 * reloc.c (_bfd_clear_contents): Replace "location" param with "buf" and "off". Bounds check "off". Return status. * cofflink.c (_bfd_coff_generic_relocate_section): Update _bfd_clear_contents call. * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Likewise. * elf32-arc.c (elf_arc_relocate_section): Likewise. * elf32-i386.c (elf_i386_relocate_section): Likewise. * elf32-metag.c (metag_final_link_relocate): Likewise. * elf32-nds32.c (nds32_elf_get_relocated_section_contents): Likewise. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. * elf32-visium.c (visium_elf_relocate_section): Likewise. * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. * elf64-x86-64.c *(elf_x86_64_relocate_section): Likewise. * libbfd-in.h (_bfd_clear_contents): Update prototype. * libbfd.h: Regenerate.
Diffstat (limited to 'bfd/reloc.c')
-rw-r--r--bfd/reloc.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 8dbb889..1686780 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -1504,15 +1504,21 @@ _bfd_relocate_contents (reloc_howto_type *howto,
relocations against discarded symbols, to make ignorable debug or unwind
information more obvious. */
-void
+bfd_reloc_status_type
_bfd_clear_contents (reloc_howto_type *howto,
bfd *input_bfd,
asection *input_section,
- bfd_byte *location)
+ bfd_byte *buf,
+ bfd_vma off)
{
bfd_vma x;
+ bfd_byte *location;
+
+ if (!bfd_reloc_offset_in_range (howto, input_bfd, input_section, off))
+ return bfd_reloc_outofrange;
/* Get the value we are going to relocate. */
+ location = buf + off;
x = read_reloc (input_bfd, location, howto);
/* Zero out the unwanted bits of X. */
@@ -1527,6 +1533,7 @@ _bfd_clear_contents (reloc_howto_type *howto,
/* Put the relocated value back in the object file. */
write_reloc (input_bfd, x, location, howto);
+ return bfd_reloc_ok;
}
/*
@@ -8336,14 +8343,14 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
&& (input_section->flags & SEC_DEBUGGING) != 0
&& link_info->input_bfds == link_info->output_bfd))
{
- bfd_byte *p;
+ bfd_vma off;
static reloc_howto_type none_howto
= HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL,
"unused", FALSE, 0, 0, FALSE);
- p = data + (*parent)->address * bfd_octets_per_byte (input_bfd);
- _bfd_clear_contents ((*parent)->howto, input_bfd, input_section,
- p);
+ off = (*parent)->address * bfd_octets_per_byte (input_bfd);
+ _bfd_clear_contents ((*parent)->howto, input_bfd,
+ input_section, data, off);
(*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
(*parent)->addend = 0;
(*parent)->howto = &none_howto;