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]

mips_elf_create_dynamic_relocation can look beyond relocs array end


Hi, list.
The following code in mips_elf_create_dynamic_relocation can look beyond
relocs array end when called in such way:
_bfd_mips_elf_relocate_section -> mips_elf_calculate_relocation ->
mips_elf_create_dynamic_relocation:

outrel[1].r_offset =
      _bfd_elf_section_offset (output_bfd, info, input_section,
rel[1].r_offset);
    outrel[2].r_offset =
      _bfd_elf_section_offset (output_bfd, info, input_section,
rel[2].r_offset);

This code deals with non-standard 64 bit ELF relocations format, but the
problem occurs while linking o32 or n32 objects. If rel points to the
last relocs (_bfd_mips_elf_relocate_section argument) array entry, then
access to rel[1] and rel[2] can cause segfault, or garbage can be read
and passed to _bfd_elf_section_offset, which can cause assertion fail in
_bfd_elf_eh_frame_section_offset. The last is a real case of ld behavior
at least when linking o32 shared libraries using binutils-2.17.50.0.12
(and binutils-2.17.50.0.15 also). Really
mips_elf_create_dynamic_relocation doesn't need rel[1] and rel[2]
records while working in 32 bit mode, maybe it would be better if it
doesn't access them in that case?

Sergey Rogozhkin

--- bfd/elfxx-mips.c	2007-04-19 18:14:24.000000000 +0400
+++ bfd/elfxx-mips.c	2007-04-28 16:15:23.000000000 +0400
@@ -4786,10 +4786,13 @@ mips_elf_create_dynamic_relocation (bfd 
 
   outrel[0].r_offset =
     _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
-  outrel[1].r_offset =
-    _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
-  outrel[2].r_offset =
-    _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
+  if (ABI_64_P (output_bfd))
+    {
+      outrel[1].r_offset = _bfd_elf_section_offset
+	(output_bfd, info, input_section, rel[1].r_offset);
+      outrel[2].r_offset = _bfd_elf_section_offset
+	(output_bfd, info, input_section, rel[2].r_offset);
+    }
 
   if (outrel[0].r_offset == MINUS_ONE)
     /* The relocation field has been deleted.  */



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