This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/2] MIPS64/BFD: Fix a crash with invalid `r_sym' in relocation


Prevent an out-of-range access and a possible segmentation fault in 
`mips_elf64_slurp_one_reloc_table':

Program received signal SIGSEGV, Segmentation fault.
mips_elf64_slurp_one_reloc_table (abfd=0x71bd90, asect=0x71cf70,
    rel_hdr=<value optimized out>, reloc_count=1,
    relents=<value optimized out>, symbols=0x7218c0, dynamic=0)
    at .../bfd/elf64-mips.c:3758
3757			      ps = symbols + rela.r_sym - 1;
3758			      s = *ps;

in the MIPS64 (n64 MIPS) ELF backend whenever an invalid symbol index is 
retrieved from the `r_sym' field of a relocation seen in input while 
running `objcopy' or `strip'.  Issue an error instead, like the generic 
ELF backend does, taking code from `elf_slurp_reloc_table_from_section', 
except for relocation types that do not refer to a symbol.

This complements commit 1f70368c21a8 ("Stop objdump crash on corrupt 
reloc table"), <https://sourceware.org/ml/binutils/2002-09/msg00332.html>, 
and commit 05a487dc8c39 ("make check fails on i686-linux-gnu"), 
<https://sourceware.org/ml/binutils/2002-09/msg00340.html>, where the 
generic ELF backend code comes from.

	bfd/
	* elf64-mips.c (mips_elf64_slurp_one_reloc_table): Issue an 
	error for out-of-range `r_sym' values.
---
Hi,

 Self-approved and will commit it along with 2/2.

  Maciej
---
 bfd/elf64-mips.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

binutils-mips64-bfd-slurp-reloc-table-inv-sym-idx-err.diff
Index: binutils/bfd/elf64-mips.c
===================================================================
--- binutils.orig/bfd/elf64-mips.c	2018-04-06 13:25:15.519149060 +0100
+++ binutils/bfd/elf64-mips.c	2018-04-06 13:46:46.068090012 +0100
@@ -3669,6 +3669,7 @@ mips_elf64_slurp_one_reloc_table (bfd *a
 {
   void *allocated;
   bfd_byte *native_relocs;
+  unsigned int symcount;
   arelent *relent;
   bfd_vma i;
   int entsize;
@@ -3694,6 +3695,11 @@ mips_elf64_slurp_one_reloc_table (bfd *a
   else
     rela_p = TRUE;
 
+  if (dynamic)
+    symcount = bfd_get_dynamic_symcount (abfd);
+  else
+    symcount = bfd_get_symcount (abfd);
+
   for (i = 0, relent = relents;
        i < reloc_count;
        i++, native_relocs += entsize)
@@ -3750,6 +3756,17 @@ mips_elf64_slurp_one_reloc_table (bfd *a
 		{
 		  if (rela.r_sym == STN_UNDEF)
 		    relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+		  else if (rela.r_sym > symcount)
+		    {
+		      _bfd_error_handler
+			/* xgettext:c-format */
+			(_("%pB(%pA): relocation %" PRIu64
+			   " has invalid symbol index %ld"),
+			 abfd, asect, (uint64_t) i, rela.r_sym);
+		      bfd_set_error (bfd_error_bad_value);
+		      relent->sym_ptr_ptr
+			= bfd_abs_section_ptr->symbol_ptr_ptr;
+		    }
 		  else
 		    {
 		      asymbol **ps, *s;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]