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] asan error on bfd bfd_simple_get_relocated_section_contents


Hi,

-fsanitize=address build crashes on an error when GDB loads a file.

https://sourceware.org/bugzilla/show_bug.cgi?id=16595

abfd->section_count unexpectedly changes between 218 and 248 in:

150 bfd_simple_get_relocated_section_contents (bfd *abfd,
[...]
218   saved_offsets = malloc (sizeof (struct saved_output_info)
219                           * abfd->section_count);
[...]
230       _bfd_generic_link_add_symbols (abfd, &link_info);
[...]
248   bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets);

_bfd_generic_link_add_symbols increases section_count

	#0  bfd_section_init (abfd=0x60280003c640, newsect=0x60620010a668) at section.c:831
	830   abfd->section_count++;
	#1  in bfd_make_section_old_way (abfd=0x60280003c640, name=0x2fe0ae0 "COMMON") at section.c:1106
	#2  in _bfd_generic_link_add_one_symbol (info=0x7fffffffccb0, abfd=0x60280003c640, name=0x6062001092b8 "symbol_01_length_40", '_' <repeats 21 times>, flags=65536, section=0x3c34220 <_bfd_std_section>, value=4, string=0x6062001092b8 "symbol_01_length_40", '_' <repeats 21 times>, copy=0, collect=0, hashp=0x7fffffffca10) at linker.c:1769
	#3  in generic_link_add_symbol_list (abfd=0x60280003c640, info=0x7fffffffccb0, symbol_count=16, symbols=0x606200109388, collect=0) at linker.c:1382
	#4  in generic_link_add_object_symbols (abfd=0x60280003c640, info=0x7fffffffccb0, collect=0) at linker.c:872
	#5  in generic_link_add_symbols (abfd=0x60280003c640, info=0x7fffffffccb0, collect=0) at linker.c:841
	#6  in _bfd_generic_link_add_symbols (abfd=0x60280003c640, info=0x7fffffffccb0) at linker.c:789
	#7  in bfd_simple_get_relocated_section_contents (abfd=0x60280003c640, sec=0x606200109d20, outbuf=0x6062001056a0 "", symbol_table=0x0) at simple.c:230

and simple_restore_output_info later reads unallocated part of saved_offsets.

READ of size 8 at 0x601c0000c5c0 thread T0
    #0 0x1124770 in simple_restore_output_info (.../gdb/gdb+0x1124770)
    #1 0x10ecd51 in bfd_map_over_sections (.../gdb/gdb+0x10ecd51)
    #2 0x1125150 in bfd_simple_get_relocated_section_contents (.../gdb/gdb+0x1125150)

No regressions on x86_64-fedora20-linux-gnu.


Thanks,
Jan
bfd/
2014-02-16  Jan Kratochvil  <jan.kratochvil@redhat.com>

	PR binutils/16595
	* simple.c (struct saved_offsets): New.
	(simple_save_output_info): Use it for ptr.
	(simple_restore_output_info): Use it for ptr.  Check section_count.
	(bfd_simple_get_relocated_section_contents): Use it for saved_offsets.

diff --git a/bfd/simple.c b/bfd/simple.c
index e5a5b58..424d5a0 100644
--- a/bfd/simple.c
+++ b/bfd/simple.c
@@ -101,14 +101,23 @@ struct saved_output_info
   asection *section;
 };
 
+struct saved_offsets
+{
+  int section_count;
+  struct saved_output_info *sections;
+};
+
 static void
 simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
 			 asection *section,
 			 void *ptr)
 {
-  struct saved_output_info *output_info = (struct saved_output_info *) ptr;
-  output_info[section->index].offset = section->output_offset;
-  output_info[section->index].section = section->output_section;
+  struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
+  struct saved_output_info *output_info;
+
+  output_info = &saved_offsets->sections[section->index];
+  output_info->offset = section->output_offset;
+  output_info->section = section->output_section;
   if ((section->flags & SEC_DEBUGGING) != 0
       || section->output_section == NULL)
     {
@@ -122,9 +131,15 @@ simple_restore_output_info (bfd *abfd ATTRIBUTE_UNUSED,
 			    asection *section,
 			    void *ptr)
 {
-  struct saved_output_info *output_info = (struct saved_output_info *) ptr;
-  section->output_offset = output_info[section->index].offset;
-  section->output_section = output_info[section->index].section;
+  struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
+  struct saved_output_info *output_info;
+
+  if (section->index >= saved_offsets->section_count)
+    return;
+
+  output_info = &saved_offsets->sections[section->index];
+  section->output_offset = output_info->offset;
+  section->output_section = output_info->section;
 }
 
 /*
@@ -157,7 +172,7 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
   struct bfd_link_callbacks callbacks;
   bfd_byte *contents, *data;
   int storage_needed;
-  void *saved_offsets;
+  struct saved_offsets saved_offsets;
 
   /* Don't apply relocation on executable and shared library.  See
      PR 4756.  */
@@ -215,15 +230,16 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
      section->output_offset to equal section->vma, which we do by setting
      section->output_section to point back to section.  Save the original
      output offset and output section to restore later.  */
-  saved_offsets = malloc (sizeof (struct saved_output_info)
-			  * abfd->section_count);
-  if (saved_offsets == NULL)
+  saved_offsets.section_count = abfd->section_count;
+  saved_offsets.sections = malloc (sizeof (*saved_offsets.sections)
+				   * saved_offsets.section_count);
+  if (saved_offsets.sections == NULL)
     {
       if (data)
 	free (data);
       return NULL;
     }
-  bfd_map_over_sections (abfd, simple_save_output_info, saved_offsets);
+  bfd_map_over_sections (abfd, simple_save_output_info, &saved_offsets);
 
   if (symbol_table == NULL)
     {
@@ -245,8 +261,8 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
   if (contents == NULL && data != NULL)
     free (data);
 
-  bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets);
-  free (saved_offsets);
+  bfd_map_over_sections (abfd, simple_restore_output_info, &saved_offsets);
+  free (saved_offsets.sections);
 
   _bfd_generic_link_hash_table_free (link_info.hash);
   return contents;

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