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]

Re: objdump segfault


On Wed, Aug 13, 2014 at 06:11:03PM +0200, Claudio Fontana wrote:
> $ objdump -x -d swtor.exe
> ...
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007ffff78222b0 in bfd_getl16 ()
>    from /usr/lib64/libbfd-2.22.52.0.2.20120424.so
> (gdb) bt
> #0  0x00007ffff78222b0 in bfd_getl16 ()
>    from /usr/lib64/libbfd-2.22.52.0.2.20120424.so
> #1  0x00007ffff7883823 in _bfd_pe_print_private_bfd_data_common ()
>    from /usr/lib64/libbfd-2.22.52.0.2.20120424.so
[snip]
> swtor.exe - https://drive.google.com/file/d/0B-d0d0AYq1f9TlpBeVd2dzkwUTA/edit?usp=sharing

The binary has a corrupted .reloc section by the look of it.
    
	* peXXigen.c (pe_print_reloc): Protect against access past end
	of .reloc section.

diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 3808d39..2fb631c 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -2092,8 +2092,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
   FILE *file = (FILE *) vfile;
   bfd_byte *data = 0;
   asection *section = bfd_get_section_by_name (abfd, ".reloc");
-  bfd_size_type i;
-  bfd_size_type start, stop;
+  bfd_byte *p, *end;
 
   if (section == NULL || section->size == 0 || !(section->flags & SEC_HAS_CONTENTS))
     return TRUE;
@@ -2108,20 +2107,20 @@ pe_print_reloc (bfd * abfd, void * vfile)
       return FALSE;
     }
 
-  start = 0;
-
-  stop = section->size;
-
-  for (i = start; i < stop;)
+  p = data;
+  end = data + section->size;
+  while (p + 8 <= end)
     {
       int j;
       bfd_vma virtual_address;
       long number, size;
+      bfd_byte *chunk_end;
 
       /* The .reloc section is a sequence of blocks, with a header consisting
 	 of two 32 bit quantities, followed by a number of 16 bit entries.  */
-      virtual_address = bfd_get_32 (abfd, data+i);
-      size = bfd_get_32 (abfd, data+i+4);
+      virtual_address = bfd_get_32 (abfd, p);
+      size = bfd_get_32 (abfd, p + 4);
+      p += 8;
       number = (size - 8) / 2;
 
       if (size == 0)
@@ -2131,9 +2130,13 @@ pe_print_reloc (bfd * abfd, void * vfile)
 	       _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
 	       (unsigned long) virtual_address, size, (unsigned long) size, number);
 
-      for (j = 0; j < number; ++j)
+      chunk_end = p + size;
+      if (chunk_end > end)
+	chunk_end = end;
+      j = 0;
+      while (p + 2 <= chunk_end)
 	{
-	  unsigned short e = bfd_get_16 (abfd, data + i + 8 + j * 2);
+	  unsigned short e = bfd_get_16 (abfd, p);
 	  unsigned int t = (e & 0xF000) >> 12;
 	  int off = e & 0x0FFF;
 
@@ -2144,20 +2147,20 @@ pe_print_reloc (bfd * abfd, void * vfile)
 		   _("\treloc %4d offset %4x [%4lx] %s"),
 		   j, off, (unsigned long) (off + virtual_address), tbl[t]);
 
+	  p += 2;
+	  j++;
+
 	  /* HIGHADJ takes an argument, - the next record *is* the
 	     low 16 bits of addend.  */
-	  if (t == IMAGE_REL_BASED_HIGHADJ)
+	  if (t == IMAGE_REL_BASED_HIGHADJ && p + 2 <= chunk_end)
 	    {
-	      fprintf (file, " (%4x)",
-		       ((unsigned int)
-			bfd_get_16 (abfd, data + i + 8 + j * 2 + 2)));
+	      fprintf (file, " (%4x)", (unsigned int) bfd_get_16 (abfd, p));
+	      p += 2;
 	      j++;
 	    }
 
 	  fprintf (file, "\n");
 	}
-
-      i += size;
     }
 
   free (data);

-- 
Alan Modra
Australia Development Lab, IBM


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