This is the mail archive of the binutils-cvs@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]

[binutils-gdb/binutils-2_25-branch] Import security fixes for readelf from the master branch:


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1dead8aee09e9ba148f6f44040122f62b5e4acea

commit 1dead8aee09e9ba148f6f44040122f62b5e4acea
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Mar 24 10:30:34 2015 +0000

    Import security fixes for readelf from the master branch:
    
    	2015-02-26  Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17512
    	* readelf.c (process_corefile_note_segment): Check for
    	inote.descdata extending beyond the end of the section.
    	(process_v850_notes): Likewise.
    
    	2015-02-24  Mike Frysinger  <vapier@gentoo.org>
    
    	PR binutils/17531
    	* readelf.c (process_symbol_table): Declare chained.  Increment it
    	in every loop.  Abort when chained is larger than nchains.  Move
    	error check outside of chain loop.
    
    	2015-02-10  Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17531
    	* readelf.c (dump_relocations): Handle printing offsets which are
    	MIN_INT.
    	(process_corefile_note_segment): Add range check of the namesz
    	field.
    
    	2015-02-06  Nick Clifton  <nickc@redhat.com>
    
    	* readelf.c (process_mips_specific): Fail if an option has an
    	invalid size.
    
    	2015-02-03  Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17531
    	* readelf.c (get_data): Change parameter types from size_t to
    	bfd_size_type.  Add checks for loss of accuracy when casting from
    	bfd_size_type to size_t.
    	(get_dynamic_data): Likewise.
    	(process_section_groups): Limit number of error messages.
    
    	2015-01-05  Nick Clifton  <nickc@redhat.com>
    
    	* readelf.c (slurp_ia64_unwind_table): Warn if the reloc could not
    	be indentified.
    	(dynamic_section_mips_val): Warn if the timestamp is invalid.
    	(print_mips_got_entry): Add a data_end parameter.  Warn if a read
    	would go beyond the end of the data, and return an error value.
    	(process_mips_specific): Do not read options from beyond the end
    	of the section.
    	Correct code to display optional data at the end of an option.
    	Warn if there are too many GOT symbols.
    	Update calls to print_mips_got_entry, and handle error returns.
    
    	2014-12-08  Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17531
    	* readelf.c (dump_ia64_unwind): Add range checks.
    	(slurp_ia64_unwind_table): Change to a boolean function.  Add
    	range checks.
    	(process_version_sections): Add range checks.
    	(get_symbol_version_string): Add check for missing section
    	headers.
    
    	2014-12-03  Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17531
    	* readelf.c (get_machine_flags): Replace call to abort with a
    	warning message and a return value.
    	(get_elf_section_flags): Likewise.
    	(get_symbol_visibility): Likewise.
    	(get_ia64_symbol_other): Likewise.
    	(get_ia64_symbol_other): Likewise.
    	(is_32bit_abs_reloc): Likewise.
    	(apply_relocations): Likewise.
    	(display_arm_attribute): Likewise.
    
    	2014-12-01  Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17512
    	* dwarf.h (struct dwarf_section): Add user_data field.
    	* dwarf.c (frame_need_space): Check for an over large register
    	number.
    	(display_debug_frames): Check the return value from
    	frame_need_space.  Check for a CFA expression that is so long the
    	start address wraps around.
    	(debug_displays): Initialise the user_data field.
    	* objdump.c (load_specific_debug_section): Save the BFD section
    	pointer in the user_data field of the dwarf_section structure.
    	(free_debug_section): Update BFD section data when freeing section
    	contents.
    	* readelf.c (load_specific_debug_section): Initialise the
    	user_data field.
    
    	2014-12-01  Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17531
    	* readelf.c (process_archive): Add range checks.
    
    	2014-11-28  Alan Modra  <amodra@gmail.com>
    
    	* readelf.c (get_32bit_elf_symbols): Cast bfd_size_type values to
    	unsigned long for %lx.
    	(get_64bit_elf_symbols, process_section_groups): Likewise.
    
    	2014-11-27  Espen Grindhaug <espen@grindhaug.org>
    	    Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17531
    	* readelf.c (get_data): Move excessive length check to earlier on
    	in the function and allow for wraparound in the arithmetic.
    	(get_32bit_elf_symbols): Terminate early if the section size is
    	zero.  Check for an invalid sh_entsize.  Check for an index
    	section with an invalid size.
    	(get_64bit_elf_symbols): Likewise.
    	(process_section_groups): Check for an invalid sh_entsize.
    
    	2014-11-21  Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17531
    	* readelf.c (process_version_sections): Prevent an infinite loop
    	processing corrupt version need data.
    	(process_corefile_note_segment): Handle corrupt notes.
    
    	2014-11-18  Nick Clifton  <nickc@redhat.com>
    
    	PR binutils/17531
    	* readelf.c (get_unwind_section_word): Skip reloc processing if
    	there are no relocs associated with the section.
    	(decode_tic6x_unwind_bytecode): Warn and return if the stack
    	pointer adjustment falls off the end of the buffer.

Diff:
---
 binutils/ChangeLog | 130 +++++++++++++++
 binutils/readelf.c | 466 ++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 485 insertions(+), 111 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 3d46b8a..1d0a844 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,133 @@
+2015-03-24  Nick Clifton  <nickc@redhat.com>
+
+	Apply from master:
+	2015-02-26  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* readelf.c (process_corefile_note_segment): Check for
+	inote.descdata extending beyond the end of the section.
+	(process_v850_notes): Likewise.
+
+	2015-02-24  Mike Frysinger  <vapier@gentoo.org>
+
+	PR binutils/17531
+	* readelf.c (process_symbol_table): Declare chained.  Increment it
+	in every loop.  Abort when chained is larger than nchains.  Move
+	error check outside of chain loop.
+
+	2015-02-10  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17531
+	* readelf.c (dump_relocations): Handle printing offsets which are
+	MIN_INT.
+	(process_corefile_note_segment): Add range check of the namesz
+	field.
+
+	2015-02-06  Nick Clifton  <nickc@redhat.com>
+
+	* readelf.c (process_mips_specific): Fail if an option has an
+	invalid size.
+
+	2015-02-03  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17531
+	* readelf.c (get_data): Change parameter types from size_t to
+	bfd_size_type.  Add checks for loss of accuracy when casting from
+	bfd_size_type to size_t.
+	(get_dynamic_data): Likewise.
+	(process_section_groups): Limit number of error messages.
+
+	2015-01-05  Nick Clifton  <nickc@redhat.com>
+
+	* readelf.c (slurp_ia64_unwind_table): Warn if the reloc could not
+	be indentified.
+	(dynamic_section_mips_val): Warn if the timestamp is invalid.
+	(print_mips_got_entry): Add a data_end parameter.  Warn if a read
+	would go beyond the end of the data, and return an error value.
+	(process_mips_specific): Do not read options from beyond the end
+	of the section.
+	Correct code to display optional data at the end of an option.
+	Warn if there are too many GOT symbols.
+	Update calls to print_mips_got_entry, and handle error returns.
+
+	2014-12-08  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17531
+	* readelf.c (dump_ia64_unwind): Add range checks.
+	(slurp_ia64_unwind_table): Change to a boolean function.  Add
+	range checks.
+	(process_version_sections): Add range checks.
+	(get_symbol_version_string): Add check for missing section
+	headers.
+
+	2014-12-03  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17531
+	* readelf.c (get_machine_flags): Replace call to abort with a
+	warning message and a return value.
+	(get_elf_section_flags): Likewise.
+	(get_symbol_visibility): Likewise.
+	(get_ia64_symbol_other): Likewise.
+	(get_ia64_symbol_other): Likewise.
+	(is_32bit_abs_reloc): Likewise.
+	(apply_relocations): Likewise.
+	(display_arm_attribute): Likewise.
+
+	2014-12-01  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17512
+	* dwarf.h (struct dwarf_section): Add user_data field.
+	* dwarf.c (frame_need_space): Check for an over large register
+	number.
+	(display_debug_frames): Check the return value from
+	frame_need_space.  Check for a CFA expression that is so long the
+	start address wraps around.
+	(debug_displays): Initialise the user_data field.
+	* objdump.c (load_specific_debug_section): Save the BFD section
+	pointer in the user_data field of the dwarf_section structure.
+	(free_debug_section): Update BFD section data when freeing section
+	contents.
+	* readelf.c (load_specific_debug_section): Initialise the
+	user_data field.
+
+	2014-12-01  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17531
+	* readelf.c (process_archive): Add range checks.
+
+	2014-11-28  Alan Modra  <amodra@gmail.com>
+
+	* readelf.c (get_32bit_elf_symbols): Cast bfd_size_type values to
+	unsigned long for %lx.
+	(get_64bit_elf_symbols, process_section_groups): Likewise.
+
+	2014-11-27  Espen Grindhaug <espen@grindhaug.org>
+	    Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17531
+	* readelf.c (get_data): Move excessive length check to earlier on
+	in the function and allow for wraparound in the arithmetic.
+	(get_32bit_elf_symbols): Terminate early if the section size is
+	zero.  Check for an invalid sh_entsize.  Check for an index
+	section with an invalid size.
+	(get_64bit_elf_symbols): Likewise.
+	(process_section_groups): Check for an invalid sh_entsize.
+
+	2014-11-21  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17531
+	* readelf.c (process_version_sections): Prevent an infinite loop
+	processing corrupt version need data.
+	(process_corefile_note_segment): Handle corrupt notes.
+
+	2014-11-18  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/17531
+	* readelf.c (get_unwind_section_word): Skip reloc processing if
+	there are no relocs associated with the section.
+	(decode_tic6x_unwind_bytecode): Warn and return if the stack
+	pointer adjustment falls off the end of the buffer.
+
 2015-02-11  Alan Modra  <amodra@gmail.com>
 
 	Apply from master.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 0c00b2f..2f8257a 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -165,7 +165,7 @@
 #endif
 
 char * program_name = "readelf";
-static long archive_file_offset;
+static unsigned long archive_file_offset;
 static unsigned long archive_file_size;
 static bfd_size_type current_file_size;
 static unsigned long dynamic_addr;
@@ -299,36 +299,62 @@ print_mode;
     }						\
   while (0)
 
-/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
+/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
+   the offset of the current archive member, if we are examining an archive.
    Put the retrieved data into VAR, if it is not NULL.  Otherwise allocate a buffer
    using malloc and fill that.  In either case return the pointer to the start of
    the retrieved data or NULL if something went wrong.  If something does go wrong
-   emit an error message using REASON as part of the context.  */
+   and REASON is not NULL then emit an error message using REASON as part of the
+   context.  */
 
 static void *
-get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
-	  const char * reason)
+get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size,
+	  bfd_size_type nmemb, const char * reason)
 {
   void * mvar;
+  bfd_size_type amt = size * nmemb;
 
   if (size == 0 || nmemb == 0)
     return NULL;
 
-  if (fseek (file, archive_file_offset + offset, SEEK_SET))
+  /* If the size_t type is smaller than the bfd_size_type, eg because
+     you are building a 32-bit tool on a 64-bit host, then make sure
+     that when the sizes are cast to (size_t) no information is lost.  */
+  if (sizeof (size_t) < sizeof (bfd_size_type)
+      && (   (bfd_size_type) ((size_t) size) != size
+	  || (bfd_size_type) ((size_t) nmemb) != nmemb))
     {
       if (reason)
-	error (_("Unable to seek to 0x%lx for %s\n"),
-	       (unsigned long) archive_file_offset + offset, reason);
+	error (_("Size truncation prevents reading 0x%llx elements of size 0x%llx for %s\n"),
+	       (unsigned long long) nmemb, (unsigned long long) size, reason);
+      return NULL;
+    }
+
+  /* Check for size overflow.  */
+  if (amt < nmemb)
+    {
+      if (reason)
+	error (_("Size overflow prevents reading 0x%llx elements of size 0x%llx for %s\n"),
+	       (unsigned long long) nmemb, (unsigned long long) size, reason);
       return NULL;
     }
 
   /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
      attempting to allocate memory when the read is bound to fail.  */
-  if (offset + archive_file_offset + size * nmemb > current_file_size)
+  if (amt > current_file_size
+      || offset + archive_file_offset + amt > current_file_size)
     {
       if (reason)
-	error (_("Reading 0x%lx bytes extends past end of file for %s\n"),
-	       (unsigned long) (size * nmemb), reason);
+	error (_("Reading 0x%llx bytes extends past end of file for %s\n"),
+	       (unsigned long long) amt, reason);
+      return NULL;
+    }
+
+  if (fseek (file, archive_file_offset + offset, SEEK_SET))
+    {
+      if (reason)
+	error (_("Unable to seek to 0x%lx for %s\n"),
+	       (unsigned long) archive_file_offset + offset, reason);
       return NULL;
     }
 
@@ -336,26 +362,26 @@ get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
   if (mvar == NULL)
     {
       /* Check for overflow.  */
-      if (nmemb < (~(size_t) 0 - 1) / size)
+      if (nmemb < (~(bfd_size_type) 0 - 1) / size)
 	/* + 1 so that we can '\0' terminate invalid string table sections.  */
-	mvar = malloc (size * nmemb + 1);
+	mvar = malloc ((size_t) amt + 1);
 
       if (mvar == NULL)
 	{
 	  if (reason)
-	    error (_("Out of memory allocating 0x%lx bytes for %s\n"),
-		   (unsigned long)(size * nmemb), reason);
+	    error (_("Out of memory allocating 0x%llx bytes for %s\n"),
+		   (unsigned long long) amt, reason);
 	  return NULL;
 	}
 
-      ((char *) mvar)[size * nmemb] = '\0';
+      ((char *) mvar)[amt] = '\0';
     }
 
-  if (fread (mvar, size, nmemb, file) != nmemb)
+  if (fread (mvar, (size_t) size, (size_t) nmemb, file) != nmemb)
     {
       if (reason)
-	error (_("Unable to read in 0x%lx bytes of %s\n"),
-	       (unsigned long)(size * nmemb), reason);
+	error (_("Unable to read in 0x%llx bytes of %s\n"),
+	       (unsigned long long) amt, reason);
       if (mvar != var)
 	free (mvar);
       return NULL;
@@ -525,7 +551,7 @@ printable_section_name (Elf_Internal_Shdr * sec)
 	{
 	  if (remaining < 2)
 	    break;
-	  
+
 	  * buf ++ = '^';
 	  * buf ++ = c + 0x40;
 	  remaining -= 2;
@@ -1539,7 +1565,10 @@ dump_relocations (FILE * file,
 		{
 		  bfd_signed_vma off = rels[i].r_addend;
 
-		  if (off < 0)
+		  /* PR 17531: file: 2e63226f.  */
+		  if (off == ((bfd_signed_vma) 1) << ((sizeof (bfd_signed_vma) * 8) - 1))
+		    printf (" + %" BFD_VMA_FMT "x", off);
+		  else if (off < 0)
 		    printf (" - %" BFD_VMA_FMT "x", - off);
 		  else
 		    printf (" + %" BFD_VMA_FMT "x", off);
@@ -1551,7 +1580,10 @@ dump_relocations (FILE * file,
 	  bfd_signed_vma off = rels[i].r_addend;
 
 	  printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
-	  if (off < 0)
+	  /* PR 17531: file: 2e63226f.  */
+	  if (off == ((bfd_signed_vma) 1) << ((sizeof (bfd_signed_vma) * 8) - 1))
+	    printf ("%" BFD_VMA_FMT "x", off);
+	  else if (off < 0)
 	    printf ("-%" BFD_VMA_FMT "x", - off);
 	  else
 	    printf ("%" BFD_VMA_FMT "x", off);
@@ -2984,7 +3016,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
 	  if (e_flags & EF_SH_FDPIC)
 	    strcat (buf, ", fdpic");
 	  break;
-          
+
         case EM_OR1K:
           if (e_flags & EF_OR1K_NODELAY)
             strcat (buf, ", no delay");
@@ -3085,7 +3117,9 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
                   strcat (buf, ", abort");
                   break;
                 default:
-                  abort ();
+		  warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
+			e_flags & EF_IA_64_VMS_COMCOD);
+		  strcat (buf, ", <unknown>");
                 }
             }
 	  break;
@@ -4323,7 +4357,7 @@ process_program_headers (FILE * file)
       /* PR binutils/12467.  */
       if (elf_header.e_phoff != 0)
 	warn (_("possibly corrupt ELF header - it has a non-zero program"
-		" header offset, but no program headers"));
+		" header offset, but no program headers\n"));
       else if (do_segments)
 	printf (_("\nThere are no program headers in this file.\n"));
       return 0;
@@ -4722,10 +4756,18 @@ get_32bit_elf_symbols (FILE * file,
   Elf_Internal_Sym * psym;
   unsigned int j;
 
+  if (section->sh_size == 0)
+    {
+      if (num_syms_return != NULL)
+	* num_syms_return = 0;
+      return NULL;
+    }
+
   /* Run some sanity checks first.  */
-  if (section->sh_entsize == 0)
+  if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
     {
-      error (_("sh_entsize is zero\n"));
+      error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
+	     printable_section_name (section), (unsigned long) section->sh_entsize);
       goto exit_point;
     }
 
@@ -4740,7 +4782,10 @@ get_32bit_elf_symbols (FILE * file,
 
   if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
     {
-      error (_("Invalid sh_entsize\n"));
+      error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
+	     (unsigned long) section->sh_size,
+	     printable_section_name (section),
+	     (unsigned long) section->sh_entsize);
       goto exit_point;
     }
 
@@ -4760,6 +4805,15 @@ get_32bit_elf_symbols (FILE * file,
                                                    _("symbol table section indicies"));
       if (shndx == NULL)
 	goto exit_point;
+      /* PR17531: file: heap-buffer-overflow */
+      else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
+	{
+	  error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
+		 printable_section_name (symtab_shndx_hdr),
+		 (unsigned long) symtab_shndx_hdr->sh_size,
+		 (unsigned long) section->sh_size);
+	  goto exit_point;
+	}
     }
 
   isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
@@ -4810,17 +4864,27 @@ get_64bit_elf_symbols (FILE * file,
   Elf_Internal_Sym * psym;
   unsigned int j;
 
+  if (section->sh_size == 0)
+    {
+      if (num_syms_return != NULL)
+	* num_syms_return = 0;
+      return NULL;
+    }
+
   /* Run some sanity checks first.  */
-  if (section->sh_entsize == 0)
+  if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
     {
-      error (_("sh_entsize is zero\n"));
+      error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
+	     printable_section_name (section),
+	     (unsigned long) section->sh_entsize);
       goto exit_point;
     }
 
   if (section->sh_size > current_file_size)
     {
       error (_("Section %s has an invalid sh_size of 0x%lx\n"),
-	     printable_section_name (section), (unsigned long) section->sh_size);
+	     printable_section_name (section),
+	     (unsigned long) section->sh_size);
       goto exit_point;
     }
 
@@ -4828,7 +4892,10 @@ get_64bit_elf_symbols (FILE * file,
 
   if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
     {
-      error (_("Invalid sh_entsize\n"));
+      error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
+	     (unsigned long) section->sh_size,
+	     printable_section_name (section),
+	     (unsigned long) section->sh_entsize);
       goto exit_point;
     }
 
@@ -4847,6 +4914,14 @@ get_64bit_elf_symbols (FILE * file,
                                                    _("symbol table section indicies"));
       if (shndx == NULL)
 	goto exit_point;
+      else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
+	{
+	  error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
+		 printable_section_name (symtab_shndx_hdr),
+		 (unsigned long) symtab_shndx_hdr->sh_size,
+		 (unsigned long) section->sh_size);
+	  goto exit_point;
+	}
     }
 
   isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
@@ -5007,7 +5082,10 @@ get_elf_section_flags (bfd_vma sh_flags)
 	      if (p != buff + field_size + 4)
 		{
 		  if (size < (10 + 2))
-		    abort ();
+		    {
+		      warn (_("Internal error: not enough buffer room for section flag info"));
+		      return _("<unknown>");
+		    }
 		  size -= 2;
 		  *p++ = ',';
 		  *p++ = ' ';
@@ -5071,7 +5149,10 @@ get_elf_section_flags (bfd_vma sh_flags)
 	  if (p != buff + field_size + 4)
 	    {
 	      if (size < (2 + 1))
-		abort ();
+		{
+		  warn (_("Internal error: not enough buffer room for section flag info"));
+		  return _("<unknown>");
+		}
 	      size -= 2;
 	      *p++ = ',';
 	      *p++ = ' ';
@@ -5086,7 +5167,10 @@ get_elf_section_flags (bfd_vma sh_flags)
 	  if (p != buff + field_size + 4)
 	    {
 	      if (size < (2 + 1))
-		abort ();
+		{
+		  warn (_("Internal error: not enough buffer room for section flag info"));
+		  return _("<unknown>");
+		}
 	      size -= 2;
 	      *p++ = ',';
 	      *p++ = ' ';
@@ -5101,7 +5185,10 @@ get_elf_section_flags (bfd_vma sh_flags)
 	  if (p != buff + field_size + 4)
 	    {
 	      if (size < (2 + 1))
-		abort ();
+		{
+		  warn (_("Internal error: not enough buffer room for section flag info"));
+		  return _("<unknown>");
+		}
 	      size -= 2;
 	      *p++ = ',';
 	      *p++ = ' ';
@@ -5762,6 +5849,16 @@ process_section_groups (FILE * file)
 		? strtab + sym->st_name : _("<corrupt>");
 	    }
 
+	  /* PR 17531: file: loop.  */
+	  if (section->sh_entsize > section->sh_size)
+	    {
+	      error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
+		     printable_section_name (section),
+		     (unsigned long) section->sh_entsize,
+		     (unsigned long) section->sh_size);
+	      break;
+	    }
+
 	  start = (unsigned char *) get_data (NULL, file, section->sh_offset,
                                               1, section->sh_size,
                                               _("section data"));
@@ -6097,7 +6194,8 @@ process_relocs (FILE * file)
 				offset_from_vma (file, rel_offset, rel_size),
 				rel_size,
 				dynamic_symbols, num_dynamic_syms,
-				dynamic_strings, dynamic_strings_length, is_rela);
+				dynamic_strings, dynamic_strings_length,
+				is_rela);
 	    }
 	}
 
@@ -6172,7 +6270,8 @@ process_relocs (FILE * file)
 		    }
 
 		  dump_relocations (file, rel_offset, rel_size,
-				    symtab, nsyms, strtab, strtablen, is_rela);
+				    symtab, nsyms, strtab, strtablen,
+				    is_rela);
 		  if (strtab)
 		    free (strtab);
 		  free (symtab);
@@ -6292,6 +6391,7 @@ dump_ia64_unwind (struct ia64_unw_aux_info * aux)
       bfd_vma offset;
       const unsigned char * dp;
       const unsigned char * head;
+      const unsigned char * end;
       const char * procname;
 
       find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
@@ -6314,6 +6414,18 @@ dump_ia64_unwind (struct ia64_unw_aux_info * aux)
       printf ("], info at +0x%lx\n",
 	      (unsigned long) (tp->info.offset - aux->seg_base));
 
+      /* PR 17531: file: 86232b32.  */
+      if (aux->info == NULL)
+	continue;
+
+      /* PR 17531: file: 0997b4d1.  */
+      if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
+	{
+	  warn (_("Invalid offset %lx in table entry %ld\n"),
+		(long) tp->info.offset, (long) (tp - aux->table));
+	  continue;
+	}
+
       head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
       stamp = byte_get ((unsigned char *) head, sizeof (stamp));
 
@@ -6331,7 +6443,11 @@ dump_ia64_unwind (struct ia64_unw_aux_info * aux)
 	}
 
       in_body = 0;
-      for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
+      end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
+      /* PR 17531: file: 16ceda89.  */
+      if (end > aux->info + aux->info_size)
+	end = aux->info + aux->info_size;
+      for (dp = head + 8; dp < end;)
 	dp = unw_decode (dp, in_body, & in_body);
     }
 }
@@ -6352,6 +6468,8 @@ slurp_ia64_unwind_table (FILE * file,
   Elf_Internal_Sym * sym;
   const char * relname;
 
+  aux->table_len = 0;
+
   /* First, find the starting address of the segment that includes
      this section: */
 
@@ -6383,10 +6501,12 @@ slurp_ia64_unwind_table (FILE * file,
   if (!table)
     return 0;
 
+  aux->table_len = size / (3 * eh_addr_size);
   aux->table = (struct ia64_unw_table_entry *)
-      xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
+    xcmalloc (aux->table_len, sizeof (aux->table[0]));
   tep = aux->table;
-  for (tp = table; tp < table + size; ++tep)
+
+  for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
     {
       tep->start.section = SHN_UNDEF;
       tep->end.section   = SHN_UNDEF;
@@ -6412,22 +6532,41 @@ slurp_ia64_unwind_table (FILE * file,
 
       if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
 			      & rela, & nrelas))
-	return 0;
+	{
+	  free (aux->table);
+	  aux->table = NULL;
+	  aux->table_len = 0;
+	  return 0;
+	}
 
       for (rp = rela; rp < rela + nrelas; ++rp)
 	{
 	  relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
 	  sym = aux->symtab + get_reloc_symindex (rp->r_info);
 
+	  /* PR 17531: file: 9fa67536.  */
+	  if (relname == NULL)
+	    {
+	      warn (_("Skipping unknown relocation type: %u\n"), get_reloc_type (rp->r_info));
+	      continue;
+	    }
+
 	  if (! const_strneq (relname, "R_IA64_SEGREL"))
 	    {
-	      warn (_("Skipping unexpected relocation type %s\n"), relname);
+	      warn (_("Skipping unexpected relocation type: %s\n"), relname);
 	      continue;
 	    }
 
 	  i = rp->r_offset / (3 * eh_addr_size);
 
-	  switch (rp->r_offset/eh_addr_size % 3)
+	  /* PR 17531: file: 5bc8d9bf.  */
+	  if (i >= aux->table_len)
+	    {
+	      warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
+	      continue;
+	    }
+
+	  switch (rp->r_offset / eh_addr_size % 3)
 	    {
 	    case 0:
 	      aux->table[i].start.section = sym->st_shndx;
@@ -6449,7 +6588,6 @@ slurp_ia64_unwind_table (FILE * file,
       free (rela);
     }
 
-  aux->table_len = size / (3 * eh_addr_size);
   return 1;
 }
 
@@ -6587,9 +6725,8 @@ ia64_process_unwind (FILE * file)
 		  (unsigned long) unwsec->sh_offset,
 		  (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
 
-	  (void) slurp_ia64_unwind_table (file, & aux, unwsec);
-
-	  if (aux.table_len > 0)
+	  if (slurp_ia64_unwind_table (file, & aux, unwsec)
+	      && aux.table_len > 0)
 	    dump_ia64_unwind (& aux);
 
 	  if (aux.table)
@@ -7089,6 +7226,13 @@ get_unwind_section_word (struct arm_unw_aux_info *  aux,
   /* Get the word at the required offset.  */
   word = byte_get (arm_sec->data + word_offset, 4);
 
+  /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128.  */
+  if (arm_sec->rela == NULL)
+    {
+      * wordp = word;
+      return TRUE;
+    }
+
   /* Look through the relocs to find the one that applies to the provided offset.  */
   wrapped = FALSE;
   for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
@@ -7583,7 +7727,14 @@ decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
 	      if ((buf[i] & 0x80) == 0)
 		break;
 	    }
-	  assert (i < sizeof (buf));
+	  /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2.  */
+	  if (i == sizeof (buf))
+	    {
+	      printf ("<corrupt sp adjust>\n");
+	      warn (_("Corrupt stack pointer adjustment detected\n"));
+	      return;
+	    }
+
 	  offset = read_uleb128 (buf, &len, buf + i + 1);
 	  assert (len == i + 1);
 	  offset = offset * 8 + 0x408;
@@ -8021,9 +8172,13 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry)
 
 	time_t atime = entry->d_un.d_val;
 	tmp = gmtime (&atime);
-	snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
-		  tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
-		  tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+	/* PR 17531: file: 6accc532.  */
+	if (tmp == NULL)
+	  snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
+	else
+	  snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
+		    tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
+		    tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 	printf (_("Time Stamp: %s"), timebuf);
       }
       break;
@@ -9119,6 +9274,10 @@ process_version_sections (FILE * file)
 		if (j < ent.vd_cnt)
 		  printf (_("  Version def aux past end of section\n"));
 
+		/* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2.  */
+		if (idx + ent.vd_next <= idx)
+		  break;
+
 		idx += ent.vd_next;
 	      }
 
@@ -9219,8 +9378,14 @@ process_version_sections (FILE * file)
 			    get_ver_flags (aux.vna_flags), aux.vna_other);
 
 		    /* Check for overflow.  */
-		    if (aux.vna_next > (size_t) (endbuf - vstart))
-		      break;
+		    if (aux.vna_next > (size_t) (endbuf - vstart)
+			|| (aux.vna_next == 0 && j < ent.vn_cnt - 1))
+		      {
+			warn (_("Invalid vna_next field of %lx\n"),
+			      aux.vna_next);
+			j = ent.vn_cnt;
+			break;
+		      }
 
 		    isum   += aux.vna_next;
 		    vstart += aux.vna_next;
@@ -9440,7 +9605,7 @@ process_version_sections (FILE * file)
 					    _("version def")) == NULL)
 				{
 				  ivd.vd_next = 0;
-				  /* PR 17531: file: 046-1082287-0.004.  */ 
+				  /* PR 17531: file: 046-1082287-0.004.  */
 				  ivd.vd_ndx  = (data[cnt + j] & VERSYM_VERSION) + 1;
 				  break;
 				}
@@ -9598,7 +9763,9 @@ get_symbol_visibility (unsigned int visibility)
     case STV_INTERNAL:	return "INTERNAL";
     case STV_HIDDEN:	return "HIDDEN";
     case STV_PROTECTED: return "PROTECTED";
-    default: abort ();
+    default:
+      error (_("Unrecognized visibility value: %u"), visibility);
+      return _("<unknown>");
     }
 }
 
@@ -9653,7 +9820,10 @@ get_ia64_symbol_other (unsigned int other)
               strcat (res, " RSV");
               break;
             default:
-              abort ();
+	      warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
+		    VMS_ST_FUNC_TYPE (other));
+	      strcat (res, " <unknown>");
+	      break;
             }
           break;
         default:
@@ -9674,7 +9844,10 @@ get_ia64_symbol_other (unsigned int other)
           strcat (res, " LNK");
           break;
         default:
-          abort ();
+	  warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
+		VMS_ST_LINKAGE (other));
+	  strcat (res, " <unknown>");
+	  break;
         }
 
       if (res[0] != 0)
@@ -9774,41 +9947,52 @@ get_symbol_index_type (unsigned int type)
 }
 
 static bfd_vma *
-get_dynamic_data (FILE * file, size_t number, unsigned int ent_size)
+get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size)
 {
   unsigned char * e_data;
   bfd_vma * i_data;
 
+  /* If the size_t type is smaller than the bfd_size_type, eg because
+     you are building a 32-bit tool on a 64-bit host, then make sure
+     that when (number) is cast to (size_t) no information is lost.  */
+  if (sizeof (size_t) < sizeof (bfd_size_type)
+      && (bfd_size_type) ((size_t) number) != number)
+    {
+      error (_("Size truncation prevents reading %llu elements of size %u\n"),
+	     (unsigned long long) number, ent_size);
+      return NULL;
+    }
+
   /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
      attempting to allocate memory when the read is bound to fail.  */
   if (ent_size * number > current_file_size)
     {
-      error (_("Invalid number of dynamic entries: %lu\n"),
-	     (unsigned long) number);
+      error (_("Invalid number of dynamic entries: %llu\n"),
+	     (unsigned long long) number);
       return NULL;
     }
 
-  e_data = (unsigned char *) cmalloc (number, ent_size);
+  e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
   if (e_data == NULL)
     {
-      error (_("Out of memory reading %lu dynamic entries\n"),
-	     (unsigned long) number);
+      error (_("Out of memory reading %llu dynamic entries\n"),
+	     (unsigned long long) number);
       return NULL;
     }
 
-  if (fread (e_data, ent_size, number, file) != number)
+  if (fread (e_data, ent_size, (size_t) number, file) != number)
     {
-      error (_("Unable to read in %lu bytes of dynamic data\n"),
-	     (unsigned long) (number * ent_size));
+      error (_("Unable to read in %llu bytes of dynamic data\n"),
+	     (unsigned long long) (number * ent_size));
       free (e_data);
       return NULL;
     }
 
-  i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
+  i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
   if (i_data == NULL)
     {
-      error (_("Out of memory allocating space for %lu dynamic entries\n"),
-	     (unsigned long) number);
+      error (_("Out of memory allocating space for %llu dynamic entries\n"),
+	     (unsigned long long) number);
       free (e_data);
       return NULL;
     }
@@ -10196,7 +10380,8 @@ process_symbol_table (FILE * file)
 
 		  vers_data = byte_get (data, 2);
 
-		  is_nobits = (psym->st_shndx < elf_header.e_shnum
+		  is_nobits = (section_headers != NULL
+			       && psym->st_shndx < elf_header.e_shnum
 			       && section_headers[psym->st_shndx].sh_type
 				  == SHT_NOBITS);
 
@@ -10357,6 +10542,7 @@ process_symbol_table (FILE * file)
       unsigned long maxlength = 0;
       unsigned long nzero_counts = 0;
       unsigned long nsyms = 0;
+      unsigned long chained;
 
       printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
 	      (unsigned long) nbuckets);
@@ -10371,20 +10557,22 @@ process_symbol_table (FILE * file)
       printf (_(" Length  Number     %% of total  Coverage\n"));
       for (hn = 0; hn < nbuckets; ++hn)
 	{
-	  for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
+	  for (si = buckets[hn], chained = 0;
+	       si > 0 && si < nchains && si < nbuckets && chained <= nchains;
+	       si = chains[si], ++chained)
 	    {
 	      ++nsyms;
 	      if (maxlength < ++lengths[hn])
 		++maxlength;
+	    }
 
-	      /* PR binutils/17531: A corrupt binary could contain broken
-		 histogram data.  Do not go into an infinite loop trying
-		 to process it.  */
-	      if (chains[si] == si)
-		{
-		  error (_("histogram chain links to itself\n"));
-		  break;
-		}
+	  /* PR binutils/17531: A corrupt binary could contain broken
+	     histogram data.  Do not go into an infinite loop trying
+	     to process it.  */
+	  if (chained > nchains)
+	    {
+	      error (_("histogram chain is corrupt\n"));
+	      break;
 	    }
 	}
 
@@ -10839,7 +11027,7 @@ is_32bit_abs_reloc (unsigned int reloc_type)
     default:
       error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
 	     elf_header.e_machine);
-      abort ();
+      return FALSE;
     }
 }
 
@@ -12105,7 +12293,8 @@ display_arm_attribute (unsigned char * p,
 	      break;
 
 	    default:
-	      abort ();
+	      printf (_("<unknown: %d>\n"), tag);
+	      break;
 	    }
 	  return p;
 
@@ -13066,10 +13255,12 @@ process_msp430x_specific (FILE * file)
 
 /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
    Print the Address, Access and Initial fields of an entry at VMA ADDR
-   and return the VMA of the next entry.  */
+   and return the VMA of the next entry, or -1 if there was a problem.
+   Does not read from DATA_END or beyond.  */
 
 static bfd_vma
-print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
+print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
+		      unsigned char * data_end)
 {
   printf ("  ");
   print_vma (addr, LONG_HEX);
@@ -13084,9 +13275,19 @@ print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
   else
     {
       bfd_vma entry;
+      unsigned char * from = data + addr - pltgot;
 
-      entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
-      print_vma (entry, LONG_HEX);
+      if (from + (is_32bit_elf ? 4 : 8) > data_end)
+	{
+	  warn (_("MIPS GOT entry extends beyond the end of available data\n"));
+	  printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
+	  return (bfd_vma) -1;
+	}
+      else
+	{
+	  entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
+	  print_vma (entry, LONG_HEX);
+	}
     }
   return addr + (is_32bit_elf ? 4 : 8);
 }
@@ -13448,7 +13649,7 @@ process_mips_specific (FILE * file)
 
       /* Find the section header so that we get the size.  */
       sect = find_section_by_type (SHT_MIPS_OPTIONS);
-      /* PR 17533 file: 012-277276-0.004.  */ 
+      /* PR 17533 file: 012-277276-0.004.  */
       if (sect == NULL)
 	{
 	  error (_("No MIPS_OPTIONS header found\n"));
@@ -13470,7 +13671,7 @@ process_mips_specific (FILE * file)
 	  offset = cnt = 0;
 	  option = iopt;
 
-	  while (offset < sect->sh_size)
+	  while (offset <= sect->sh_size - sizeof (* eopt))
 	    {
 	      Elf_External_Options * eoption;
 
@@ -13481,6 +13682,13 @@ process_mips_specific (FILE * file)
 	      option->section = BYTE_GET (eoption->section);
 	      option->info = BYTE_GET (eoption->info);
 
+	      /* PR 17531: file: ffa0fa3b.  */
+	      if (option->size < sizeof (* eopt)
+		  || offset + option->size > sect->sh_size)
+		{
+		  error (_("Invalid size (%u) for MIPS option\n"), option->size);
+		  return 0;
+		}
 	      offset += option->size;
 
 	      ++option;
@@ -13491,6 +13699,7 @@ process_mips_specific (FILE * file)
 		  printable_section_name (sect), cnt);
 
 	  option = iopt;
+	  offset = 0;
 
 	  while (cnt-- > 0)
 	    {
@@ -13627,13 +13836,18 @@ process_mips_specific (FILE * file)
 
 	      len = sizeof (* eopt);
 	      while (len < option->size)
-		if (((char *) option)[len] >= ' '
-		    && ((char *) option)[len] < 0x7f)
-		  printf ("%c", ((char *) option)[len++]);
-		else
-		  printf ("\\%03o", ((char *) option)[len++]);
+		{
+		  char datum = * ((char *) eopt + offset + len);
+
+		  if (ISPRINT (datum))
+		    printf ("%c", datum);
+		  else
+		    printf ("\\%03o", datum);
+		  len ++;
+		}
 
 	      fputs ("\n", stdout);
+	      offset += option->size;
 	      ++option;
 	    }
 
@@ -13723,6 +13937,7 @@ process_mips_specific (FILE * file)
       bfd_vma ent, local_end, global_end;
       size_t i, offset;
       unsigned char * data;
+      unsigned char * data_end;
       int addr_size;
 
       ent = pltgot;
@@ -13733,18 +13948,25 @@ process_mips_specific (FILE * file)
       if (symtabno < gotsym)
 	{
 	  error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
-		 (long) gotsym, (long) symtabno);
+		 (unsigned long) gotsym, (unsigned long) symtabno);
 	  return 0;
 	}
- 
+
       global_end = local_end + (symtabno - gotsym) * addr_size;
-      assert (global_end >= local_end);
+      /* PR 17531: file: 54c91a34.  */
+      if (global_end < local_end)
+	{
+	  error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
+	  return 0;
+	}
+
       offset = offset_from_vma (file, pltgot, global_end - pltgot);
       data = (unsigned char *) get_data (NULL, file, offset,
                                          global_end - pltgot, 1,
 					 _("Global Offset Table data"));
       if (data == NULL)
 	return 0;
+      data_end = data + (global_end - pltgot);
 
       printf (_("\nPrimary GOT:\n"));
       printf (_(" Canonical gp value: "));
@@ -13755,14 +13977,18 @@ process_mips_specific (FILE * file)
       printf (_("  %*s %10s %*s Purpose\n"),
 	      addr_size * 2, _("Address"), _("Access"),
 	      addr_size * 2, _("Initial"));
-      ent = print_mips_got_entry (data, pltgot, ent);
+      ent = print_mips_got_entry (data, pltgot, ent, data_end);
       printf (_(" Lazy resolver\n"));
+      if (ent == (bfd_vma) -1)
+	goto got_print_fail;
       if (data
 	  && (byte_get (data + ent - pltgot, addr_size)
 	      >> (addr_size * 8 - 1)) != 0)
 	{
-	  ent = print_mips_got_entry (data, pltgot, ent);
+	  ent = print_mips_got_entry (data, pltgot, ent, data_end);
 	  printf (_(" Module pointer (GNU extension)\n"));
+	  if (ent == (bfd_vma) -1)
+	    goto got_print_fail;
 	}
       printf ("\n");
 
@@ -13774,8 +14000,10 @@ process_mips_specific (FILE * file)
 		  addr_size * 2, _("Initial"));
 	  while (ent < local_end)
 	    {
-	      ent = print_mips_got_entry (data, pltgot, ent);
+	      ent = print_mips_got_entry (data, pltgot, ent, data_end);
 	      printf ("\n");
+	      if (ent == (bfd_vma) -1)
+		goto got_print_fail;
 	    }
 	  printf ("\n");
 	}
@@ -13798,7 +14026,7 @@ process_mips_specific (FILE * file)
 
 	  for (i = gotsym; i < symtabno; i++)
 	    {
-	      ent = print_mips_got_entry (data, pltgot, ent);
+	      ent = print_mips_got_entry (data, pltgot, ent, data_end);
 	      printf (" ");
 
 	      if (dynamic_symbols == NULL)
@@ -13822,10 +14050,13 @@ process_mips_specific (FILE * file)
 			(unsigned long) i);
 
 	      printf ("\n");
+	      if (ent == (bfd_vma) -1)
+		break;
 	    }
 	  printf ("\n");
 	}
 
+    got_print_fail:
       if (data)
 	free (data);
     }
@@ -14490,7 +14721,7 @@ print_ia64_vms_note (Elf_Internal_Note * pnote)
     case NT_VMS_FPMODE:
       printf (_("   Floating Point mode: "));
       printf ("0x%016" BFD_VMA_FMT "x\n",
-              (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
+              (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
       break;
     case NT_VMS_LINKTIME:
       printf (_("   Link time: "));
@@ -14513,9 +14744,9 @@ print_ia64_vms_note (Elf_Internal_Note * pnote)
         ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
       printf (_("\n   Link flags  : "));
       printf ("0x%016" BFD_VMA_FMT "x\n",
-              (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
+              (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
       printf (_("   Header flags: 0x%08x\n"),
-              (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
+              (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
       printf (_("   Image id    : %s\n"), pnote->descdata + 32);
       break;
 #endif
@@ -14600,6 +14831,7 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 {
   Elf_External_Note * pnotes;
   Elf_External_Note * external;
+  char * end;
   int res = 1;
 
   if (length <= 0)
@@ -14616,13 +14848,14 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 	  (unsigned long) offset, (unsigned long) length);
   printf (_("  %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
 
-  while ((char *) external < (char *) pnotes + length)
+  end = (char *) pnotes + length;
+  while ((char *) external < end)
     {
       Elf_Internal_Note inote;
       size_t min_notesz;
       char *next;
       char * temp = NULL;
-      size_t data_remaining = ((char *) pnotes + length) - (char *) external;
+      size_t data_remaining = end - (char *) external;
 
       if (!is_ia64_vms ())
 	{
@@ -14640,6 +14873,14 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 	  inote.namedata = external->name;
 	  inote.descsz   = BYTE_GET (external->descsz);
 	  inote.descdata = inote.namedata + align_power (inote.namesz, 2);
+	  /* PR 17531: file: 3443835e.  */
+	  if (inote.descdata < (char *) pnotes || inote.descdata > end)
+	    {
+	      warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
+	      inote.descdata = inote.namedata;
+	      inote.namesz   = 0;
+	    }
+
 	  inote.descpos  = offset + (inote.descdata - (char *) pnotes);
 	  next = inote.descdata + align_power (inote.descsz, 2);
 	}
@@ -14669,6 +14910,9 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 
       if (inote.descdata < (char *) external + min_notesz
 	  || next < (char *) external + min_notesz
+	  /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4.  */
+	  || inote.namedata + inote.namesz < inote.namedata
+	  || inote.descdata + inote.descsz < inote.descdata
 	  || data_remaining < (size_t)(next - (char *) external))
 	{
 	  warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
@@ -14687,7 +14931,6 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
       if (inote.namedata[inote.namesz - 1] != '\0')
 	{
 	  temp = (char *) malloc (inote.namesz + 1);
-
 	  if (temp == NULL)
 	    {
 	      error (_("Out of memory allocating space for inote name\n"));
@@ -15112,11 +15355,11 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
 	error (_("%s: unable to dump the index as none was found\n"), file_name);
       else
 	{
-	  unsigned int i, l;
+	  unsigned long i, l;
 	  unsigned long current_pos;
 
-	  printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
-		  file_name, (long) arch.index_num, arch.sym_size);
+	  printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
+		  file_name, (unsigned long) arch.index_num, arch.sym_size);
 	  current_pos = ftell (file);
 
 	  for (i = l = 0; i < arch.index_num; i++)
@@ -15147,8 +15390,9 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
 			 file_name);
 		  break;
 		}
-	      printf ("\t%s\n", arch.sym_table + l);
-	      l += strlen (arch.sym_table + l) + 1;
+	      /* PR 17531: file: 0b6630b2.  */
+	      printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
+	      l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
 	    }
 
 	  if (arch.uses_64bit_indicies)


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