[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

rpms/binutils/FC-4 binutils-2.15.94.0.2-robustify2.patch, NONE, 1.1 binutils-2.15.94.0.2-robustify3.patch, NONE, 1.1 binutils-2.15.94.0.2-robustify4.patch, NONE, 1.1 binutils-2.15.94.0.2-robustify5.patch, NONE, 1.1 binutils-2.15.94.0.2-robustify6.patch, NONE, 1.1 binutils-2.15.94.0.2-robustify.patch, 1.1, 1.2 binutils.spec, 1.54, 1.55



Author: jakub

Update of /cvs/dist/rpms/binutils/FC-4
In directory cvs.devel.redhat.com:/tmp/cvs-serv5265

Modified Files:
	binutils-2.15.94.0.2-robustify.patch binutils.spec 
Added Files:
	binutils-2.15.94.0.2-robustify2.patch 
	binutils-2.15.94.0.2-robustify3.patch 
	binutils-2.15.94.0.2-robustify4.patch 
	binutils-2.15.94.0.2-robustify5.patch 
	binutils-2.15.94.0.2-robustify6.patch 
Log Message:
2.15.94.0.2.2-2.1


binutils-2.15.94.0.2-robustify2.patch:
 objdump.c |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

--- NEW FILE binutils-2.15.94.0.2-robustify2.patch ---
2005-06-09  Jakub Jelinek  <jakub redhat com>

	* objdump.c (disassemble_bytes): Don't crash if q->howto == NULL.
	If q->howto->name == NULL, print q->howto->type as number instead.
	(dump_reloc_set): Likewise.

--- binutils/objdump.c.jj	2005-05-13 23:44:24.000000000 +0200
+++ binutils/objdump.c	2005-06-06 14:20:48.000000000 +0200
@@ -1570,7 +1570,12 @@ disassemble_bytes (struct disassemble_in
 	      objdump_print_value (section->vma - rel_offset + q->address,
 				   info, TRUE);
 
-	      printf (": %s\t", q->howto->name);
+	      if (q->howto == NULL)
+		printf (": *unknown*\t");
+	      else if (q->howto->name)
+		printf (": %s\t", q->howto->name);
+	      else
+		printf (": %d\t", q->howto->type);
 
 	      if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
 		printf ("*unknown*");
@@ -2465,23 +2470,20 @@ dump_reloc_set (bfd *abfd, asection *sec
 	  section_name = NULL;
 	}
 
+      bfd_printf_vma (abfd, q->address);
+      if (q->howto == NULL)
+	printf (" *unknown*         ");
+      else if (q->howto->name)
+	printf (" %-16s  ", q->howto->name);
+      else
+	printf (" %-16d  ", q->howto->type);
       if (sym_name)
-	{
-	  bfd_printf_vma (abfd, q->address);
-	  if (q->howto->name)
-	    printf (" %-16s  ", q->howto->name);
-	  else
-	    printf (" %-16d  ", q->howto->type);
-	  objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
-	}
+	objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
       else
 	{
 	  if (section_name == NULL)
 	    section_name = "*unknown*";
-	  bfd_printf_vma (abfd, q->address);
-	  printf (" %-16s  [%s]",
-		  q->howto->name,
-		  section_name);
+	  printf ("[%s]", section_name);
 	}
 
       if (q->addend)

binutils-2.15.94.0.2-robustify3.patch:
 readelf.c |  380 ++++++++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 250 insertions(+), 130 deletions(-)

--- NEW FILE binutils-2.15.94.0.2-robustify3.patch ---
2005-06-09  Jakub Jelinek  <jakub redhat com>

	* readelf.c (cmalloc, xcmalloc, xcrealloc): New functions.
	(get_data): Add nmemb argument.  Return NULL if nmemb * size
	overflows.  If var == NULL, allocate one extra byte and
	clear it.
	(slurp_rela_relocs, slurp_rel_relocs, get_32bit_program_headers,
	get_64bit_program_headers, get_program_headers,
	get_32bit_section_headers, get_64bit_section_headers,
	get_32bit_elf_symbols, get_64bit_elf_symbols, process_section_headers,
	process_section_groups, process_relocs, slurp_ia64_unwind_table,
	ia64_process_unwind, slurp_hppa_unwind_table, hppa_process_unwind,
	get_32bit_dynamic_section, get_64bit_dynamic_section,
	process_dynamic_section, process_version_sections, get_dynamic_data,
	process_symbol_table, dump_section, load_debug_str, load_debug_loc,
	load_debug_range, get_debug_info, frame_need_space,
	display_debug_frames, display_debug_section, process_mips_specific,
	process_gnu_liblist, process_corefile_note_segment): Adjust get_data
	callers.  Use cmalloc, xcmalloc and xcrealloc instead of
	{m,xm,xre}alloc where passed size is a product of 2 numbers.

	* readelf.c (print_mode): Fix comment typo.
	(slurp_rela_relocs, slurp_rel_relocs): Fix memory leaks.
	(dump_relocations): Fix a thinko in check for invalid st_name.
	(process_program_headers): Don't crash if string_table is NULL.
	(process_section_headers): Don't crash if e_shstrndx is invalid.
	Ensure string_table_length is 0 if string_table == NULL.
	Don't return just because string_table is NULL.
	(process_section_groups): Don't crash if symtab's sh_link or
	symbol's st_name is invalid.  Fix a memory leak.  Fix check for
	invalid section number entry.
	(process_relocs): Don't crash if relocation or symbol section's
	sh_link is invalid.
	(slurp_ia64_unwind_table, slurp_hppa_unwind_table): Don't crash if
	relocation section's sh_info is invalid.
	(ia64_process_unwind, hppa_process_unwind): Don't crash if symbol
	table's sh_link is invalid.
	(process_version_sections): Don't crash on version or symbol
	section's sh_link is invalid.  Don't crash if symbol's st_shndx
	is invalid.
	(process_symbol_table): Don't crash if string table is corrupt
	or symbol's st_name, st_shndx, vna_name or vda_name is invalid.
	(debug_apply_rela_addends): Don't crash if relocation section's
	sh_info or sh_link is invalid.
	(process_gnu_liblist): Don't crash if liblist section's sh_link
	or entry's l_name is invalid.

2005-05-24  H.J. Lu  <hongjiu lu intel com>

	* readelf.c (process_section_groups): Check if the section member
	index is valid.

--- binutils/readelf.c.jj	2005-06-09 10:58:53.000000000 +0200
+++ binutils/readelf.c	2005-06-09 14:29:23.000000000 +0200
@@ -203,7 +203,7 @@ unsigned int num_dump_sects = 0;
 #define DISASS_DUMP	(1 << 1)
 #define DEBUG_DUMP	(1 << 2)
 
-/* How to rpint a vma value.  */
+/* How to print a vma value.  */
 typedef enum print_mode
 {
   HEX,
@@ -297,11 +297,42 @@ warn (const char *message, ...)
 }
 
 static void *
-get_data (void *var, FILE *file, long offset, size_t size, const char *reason)
+cmalloc (size_t nmemb, size_t size)
+{
+  /* Check for overflow.  */
+  if (nmemb >= ~(size_t) 0 / size)
+    return NULL;
+  else
+    return malloc (nmemb * size);
+}
+
+static void *
+xcmalloc (size_t nmemb, size_t size)
+{
+  /* Check for overflow.  */
+  if (nmemb >= ~(size_t) 0 / size)
+    return NULL;
+  else
+    return xmalloc (nmemb * size);
+}
+
+static void *
+xcrealloc (void *ptr, size_t nmemb, size_t size)
+{
+  /* Check for overflow.  */
+  if (nmemb >= ~(size_t) 0 / size)
+    return NULL;
+  else
+    return xrealloc (ptr, nmemb * size);
+}
+
+static void *
+get_data (void *var, FILE *file, long offset, size_t size, size_t nmemb,
+	  const char *reason)
 {
   void *mvar;
 
-  if (size == 0)
+  if (size == 0 || nmemb == 0)
     return NULL;
 
   if (fseek (file, archive_file_offset + offset, SEEK_SET))
@@ -314,19 +345,24 @@ get_data (void *var, FILE *file, long of
   mvar = var;
   if (mvar == NULL)
     {
-      mvar = malloc (size);
+      /* Check for overflow.  */
+      if (nmemb < (~(size_t) 0 - 1) / size)
+	/* + 1 so that we can '\0' terminate invalid string table sections.  */
+	mvar = malloc (size * nmemb + 1);
 
       if (mvar == NULL)
 	{
 	  error (_("Out of memory allocating 0x%x bytes for %s\n"),
-		 size, reason);
+		 size * nmemb, reason);
 	  return NULL;
 	}
+
+      ((char *) mvar)[size * nmemb] = '\0';
     }
 
-  if (fread (mvar, size, 1, file) != 1)
+  if (fread (mvar, size, nmemb, file) != nmemb)
     {
-      error (_("Unable to read in 0x%x bytes of %s\n"), size, reason);
+      error (_("Unable to read in 0x%x bytes of %s\n"), size * nmemb, reason);
       if (mvar != var)
 	free (mvar);
       return NULL;
@@ -747,16 +783,17 @@ slurp_rela_relocs (FILE *file,
     {
       Elf32_External_Rela *erelas;
 
-      erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+      erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
       if (!erelas)
 	return 0;
 
       nrelas = rel_size / sizeof (Elf32_External_Rela);
 
-      relas = malloc (nrelas * sizeof (Elf_Internal_Rela));
+      relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
 
       if (relas == NULL)
 	{
+	  free (erelas);
 	  error (_("out of memory parsing relocs"));
 	  return 0;
 	}
@@ -774,16 +811,17 @@ slurp_rela_relocs (FILE *file,
     {
       Elf64_External_Rela *erelas;
 
-      erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+      erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
       if (!erelas)
 	return 0;
 
       nrelas = rel_size / sizeof (Elf64_External_Rela);
 
-      relas = malloc (nrelas * sizeof (Elf_Internal_Rela));
+      relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
 
       if (relas == NULL)
 	{
+	  free (erelas);
 	  error (_("out of memory parsing relocs"));
 	  return 0;
 	}
@@ -817,16 +855,17 @@ slurp_rel_relocs (FILE *file,
     {
       Elf32_External_Rel *erels;
 
-      erels = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+      erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
       if (!erels)
 	return 0;
 
       nrels = rel_size / sizeof (Elf32_External_Rel);
 
-      rels = malloc (nrels * sizeof (Elf_Internal_Rela));
+      rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
 
       if (rels == NULL)
 	{
+	  free (erels);
 	  error (_("out of memory parsing relocs"));
 	  return 0;
 	}
@@ -844,16 +883,17 @@ slurp_rel_relocs (FILE *file,
     {
       Elf64_External_Rel *erels;
 
-      erels = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+      erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
       if (!erels)
 	return 0;
 
       nrels = rel_size / sizeof (Elf64_External_Rel);
 
-      rels = malloc (nrels * sizeof (Elf_Internal_Rela));
+      rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
 
       if (rels == NULL)
 	{
+	  free (erels);
 	  error (_("out of memory parsing relocs"));
 	  return 0;
 	}
@@ -1271,7 +1311,7 @@ dump_relocations (FILE *file,
 		}
 	      else if (strtab == NULL)
 		printf (_("<string table index: %3ld>"), psym->st_name);
-	      else if (psym->st_name > strtablen)
+	      else if (psym->st_name >= strtablen)
 		printf (_("<corrupt string table index: %3ld>"), psym->st_name);
 	      else
 		print_symbol (22, strtab + psym->st_name);
@@ -3047,7 +3087,7 @@ get_32bit_program_headers (FILE *file, E
   unsigned int i;
 
   phdrs = get_data (NULL, file, elf_header.e_phoff,
-		    elf_header.e_phentsize * elf_header.e_phnum,
+		    elf_header.e_phentsize, elf_header.e_phnum,
 		    _("program headers"));
   if (!phdrs)
     return 0;
@@ -3080,7 +3120,7 @@ get_64bit_program_headers (FILE *file, E
   unsigned int i;
 
   phdrs = get_data (NULL, file, elf_header.e_phoff,
-		    elf_header.e_phentsize * elf_header.e_phnum,
+		    elf_header.e_phentsize, elf_header.e_phnum,
 		    _("program headers"));
   if (!phdrs)
     return 0;
@@ -3115,7 +3155,7 @@ get_program_headers (FILE *file)
   if (program_headers != NULL)
     return 1;
 
-  phdrs = malloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
+  phdrs = cmalloc (elf_header.e_phnum, sizeof (Elf_Internal_Phdr));
 
   if (phdrs == NULL)
     {
@@ -3334,13 +3374,11 @@ process_program_headers (FILE *file)
 	putc ('\n', stdout);
     }
 
-  if (do_segments && section_headers != NULL)
+  if (do_segments && section_headers != NULL && string_table != NULL)
     {
       printf (_("\n Section to Segment mapping:\n"));
       printf (_("  Segment Sections...\n"));
 
-      assert (string_table != NULL);
-
       for (i = 0; i < elf_header.e_phnum; i++)
 	{
 	  unsigned int j;
@@ -3418,11 +3456,11 @@ get_32bit_section_headers (FILE *file, u
   unsigned int i;
 
   shdrs = get_data (NULL, file, elf_header.e_shoff,
-		    elf_header.e_shentsize * num, _("section headers"));
+		    elf_header.e_shentsize, num, _("section headers"));
   if (!shdrs)
     return 0;
 
-  section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
+  section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
 
   if (section_headers == NULL)
     {
@@ -3459,11 +3497,11 @@ get_64bit_section_headers (FILE *file, u
   unsigned int i;
 
   shdrs = get_data (NULL, file, elf_header.e_shoff,
-		    elf_header.e_shentsize * num, _("section headers"));
+		    elf_header.e_shentsize, num, _("section headers"));
   if (!shdrs)
     return 0;
 
-  section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
+  section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
 
   if (section_headers == NULL)
     {
@@ -3502,7 +3540,7 @@ get_32bit_elf_symbols (FILE *file, Elf_I
   Elf_Internal_Sym *psym;
   unsigned int j;
 
-  esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
+  esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
 		    _("symbols"));
   if (!esyms)
     return NULL;
@@ -3513,7 +3551,7 @@ get_32bit_elf_symbols (FILE *file, Elf_I
 	  == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
     {
       shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
-			symtab_shndx_hdr->sh_size, _("symtab shndx"));
+			1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
       if (!shndx)
 	{
 	  free (esyms);
@@ -3522,7 +3560,7 @@ get_32bit_elf_symbols (FILE *file, Elf_I
     }
 
   number = section->sh_size / section->sh_entsize;
-  isyms = malloc (number * sizeof (Elf_Internal_Sym));
+  isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
 
   if (isyms == NULL)
     {
@@ -3565,7 +3603,7 @@ get_64bit_elf_symbols (FILE *file, Elf_I
   Elf_Internal_Sym *psym;
   unsigned int j;
 
-  esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
+  esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
 		    _("symbols"));
   if (!esyms)
     return NULL;
@@ -3576,7 +3614,7 @@ get_64bit_elf_symbols (FILE *file, Elf_I
 	  == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
     {
       shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
-			symtab_shndx_hdr->sh_size, _("symtab shndx"));
+			1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
       if (!shndx)
 	{
 	  free (esyms);
@@ -3585,7 +3623,7 @@ get_64bit_elf_symbols (FILE *file, Elf_I
     }
 
   number = section->sh_size / section->sh_entsize;
-  isyms = malloc (number * sizeof (Elf_Internal_Sym));
+  isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
 
   if (isyms == NULL)
     {
@@ -3694,17 +3732,17 @@ process_section_headers (FILE *file)
     return 0;
 
   /* Read in the string table, so that we have names to display.  */
-  section = SECTION_HEADER (elf_header.e_shstrndx);
-
-  if (section->sh_size != 0)
+  if (SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum)
     {
-      string_table = get_data (NULL, file, section->sh_offset,
-			       section->sh_size, _("string table"));
+      section = SECTION_HEADER (elf_header.e_shstrndx);
 
-      if (string_table == NULL)
-	return 0;
+      if (section->sh_size != 0)
+	{
+	  string_table = get_data (NULL, file, section->sh_offset,
+				   1, section->sh_size, _("string table"));
 
-      string_table_length = section->sh_size;
+	  string_table_length = string_table != NULL ? section->sh_size : 0;
+	}
     }
 
   /* Scan the sections for the dynamic symbol table
@@ -3741,7 +3779,7 @@ process_section_headers (FILE *file)
 	    }
 
 	  dynamic_strings = get_data (NULL, file, section->sh_offset,
-				      section->sh_size, _("dynamic strings"));
+				      1, section->sh_size, _("dynamic strings"));
 	  dynamic_strings_length = section->sh_size;
 	}
       else if (section->sh_type == SHT_SYMTAB_SHNDX)
@@ -3928,6 +3966,7 @@ process_section_groups (FILE *file)
   Elf_Internal_Shdr *symtab_sec, *strtab_sec;
   Elf_Internal_Sym *symtab;
   char *strtab;
+  size_t strtab_size;
 
   /* Don't process section groups unless needed.  */
   if (!do_unwind && !do_section_groups)
@@ -3984,6 +4023,7 @@ process_section_groups (FILE *file)
   strtab_sec = NULL;
   symtab = NULL;
   strtab = NULL;
+  strtab_size = 0;
   for (i = 0, section = section_headers, group = section_groups;
        i < elf_header.e_shnum;
        i++, section++)
@@ -3997,8 +4037,9 @@ process_section_groups (FILE *file)
 	  Elf_Internal_Sym *sym;
 
 	  /* Get the symbol table.  */
-	  sec = SECTION_HEADER (section->sh_link);
-	  if (sec->sh_type != SHT_SYMTAB)
+	  if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum
+	      || ((sec = SECTION_HEADER (section->sh_link))->sh_type
+		  != SHT_SYMTAB))
 	    {
 	      error (_("Bad sh_link in group section `%s'\n"), name);
 	      continue;
@@ -4024,26 +4065,41 @@ process_section_groups (FILE *file)
 		}
 
 	      group_name = SECTION_NAME (section_headers + sec_index);
+	      strtab_sec = NULL;
+	      if (strtab)
+		free (strtab);
 	      strtab = NULL;
+	      strtab_size = 0;
 	    }
 	  else
 	    {
 	      /* Get the string table.  */
-	      sec = SECTION_HEADER (symtab_sec->sh_link);
-	      if (strtab_sec != sec)
+	      if (SECTION_HEADER_INDEX (symtab_sec->sh_link)
+		  >= elf_header.e_shnum)
+		{
+		  strtab_sec = NULL;
+		  if (strtab)
+		    free (strtab);
+		  strtab = NULL;
+		  strtab_size = 0;
+		}
+	      else if (strtab_sec
+		       != (sec = SECTION_HEADER (symtab_sec->sh_link)))
 		{
 		  strtab_sec = sec;
 		  if (strtab)
 		    free (strtab);
 		  strtab = get_data (NULL, file, strtab_sec->sh_offset,
-				     strtab_sec->sh_size,
+				     1, strtab_sec->sh_size,
 				     _("string table"));
+		  strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
 		}
-	      group_name = strtab + sym->st_name;
+	      group_name = sym->st_name < strtab_size
+			   ? strtab + sym->st_name : "<corrupt>";
 	    }
 
 	  start = get_data (NULL, file, section->sh_offset,
-			    section->sh_size, _("section data"));
+			    1, section->sh_size, _("section data"));
 
 	  indices = start;
 	  size = (section->sh_size / section->sh_entsize) - 1;
@@ -4067,6 +4123,19 @@ process_section_groups (FILE *file)
 	      entry = byte_get (indices, 4);
 	      indices += 4;
 
+	      if (SECTION_HEADER_INDEX (entry) >= elf_header.e_shnum)
+		{
+		  error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
+			 entry, i, elf_header.e_shnum - 1);
+		  continue;
+		}
+	      else if (entry >= SHN_LORESERVE && entry <= SHN_HIRESERVE)
+		{
+		  error (_("invalid section [%5u] in group section [%5u]\n"),
+			 entry, i);
+		  continue;
+		}
+
 	      if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
 		  != NULL)
 		{
@@ -4098,8 +4167,7 @@ process_section_groups (FILE *file)
 	      if (do_section_groups)
 		{
 		  sec = SECTION_HEADER (entry);
-		  printf ("   [%5u]   %s\n",
-			  entry, SECTION_NAME (sec));
+		  printf ("   [%5u]   %s\n", entry, SECTION_NAME (sec));
 		}
 
 	      g = xmalloc (sizeof (struct group_list));
@@ -4230,12 +4298,14 @@ process_relocs (FILE *file)
 
 	      is_rela = section->sh_type == SHT_RELA;
 
-	      if (section->sh_link)
+	      if (section->sh_link
+		  && SECTION_HEADER_INDEX (section->sh_link)
+		     < elf_header.e_shnum)
 		{
 		  Elf_Internal_Shdr *symsec;
 		  Elf_Internal_Sym *symtab;
 		  unsigned long nsyms;
-		  unsigned long strtablen;
+		  unsigned long strtablen = 0;
 		  char *strtab = NULL;
 
 		  symsec = SECTION_HEADER (section->sh_link);
@@ -4245,11 +4315,16 @@ process_relocs (FILE *file)
 		  if (symtab == NULL)
 		    continue;
 
-		  strsec = SECTION_HEADER (symsec->sh_link);
+		  if (SECTION_HEADER_INDEX (symsec->sh_link)
+		      < elf_header.e_shnum)
+		    {
+		      strsec = SECTION_HEADER (symsec->sh_link);
 
-		  strtab = get_data (NULL, file, strsec->sh_offset,
-				     strsec->sh_size, _("string table"));
-		  strtablen = strtab == NULL ? 0 : strsec->sh_size;
+		      strtab = get_data (NULL, file, strsec->sh_offset,
+					 1, strsec->sh_size,
+					 _("string table"));
+		      strtablen = strtab == NULL ? 0 : strsec->sh_size;
+		    }
 
 		  dump_relocations (file, rel_offset, rel_size,
 				    symtab, nsyms, strtab, strtablen, is_rela);
@@ -4445,11 +4520,11 @@ slurp_ia64_unwind_table (FILE *file,
 
   /* Second, build the unwind table from the contents of the unwind section:  */
   size = sec->sh_size;
-  table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
+  table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
   if (!table)
     return 0;
 
-  tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0]));
+  tep = aux->table = xcmalloc (size / (3 * addr_size), sizeof (aux->table[0]));
   for (tp = table; tp < table + size; tp += 3 * addr_size, ++tep)
     {
       tep->start.section = SHN_UNDEF;
@@ -4480,6 +4555,7 @@ slurp_ia64_unwind_table (FILE *file,
        ++relsec)
     {
       if (relsec->sh_type != SHT_RELA
+	  || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
 	  || SECTION_HEADER (relsec->sh_info) != sec)
 	continue;
 
@@ -4547,15 +4623,16 @@ ia64_process_unwind (FILE *file)
 
   for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
     {
-      if (sec->sh_type == SHT_SYMTAB)
+      if (sec->sh_type == SHT_SYMTAB
+	  && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
 	{
 	  aux.nsyms = sec->sh_size / sec->sh_entsize;
 	  aux.symtab = GET_ELF_SYMBOLS (file, sec);
 
 	  strsec = SECTION_HEADER (sec->sh_link);
-	  aux.strtab_size = strsec->sh_size;
 	  aux.strtab = get_data (NULL, file, strsec->sh_offset,
-				 aux.strtab_size, _("string table"));
+				 1, strsec->sh_size, _("string table"));
+	  aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
 	}
       else if (sec->sh_type == SHT_IA_64_UNWIND)
 	unwcount++;
@@ -4636,7 +4713,7 @@ ia64_process_unwind (FILE *file)
 	{
 	  aux.info_size = sec->sh_size;
 	  aux.info_addr = sec->sh_addr;
-	  aux.info = get_data (NULL, file, sec->sh_offset, aux.info_size,
+	  aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
 			       _("unwind info"));
 
 	  printf (_("\nUnwind section "));
@@ -4830,13 +4907,13 @@ slurp_hppa_unwind_table (FILE *file,
   /* Second, build the unwind table from the contents of the unwind
      section.  */
   size = sec->sh_size;
-  table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
+  table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
   if (!table)
     return 0;
 
   unw_ent_size = 2 * addr_size + 8;
 
-  tep = aux->table = xmalloc (size / unw_ent_size * sizeof (aux->table[0]));
+  tep = aux->table = xcmalloc (size / unw_ent_size, sizeof (aux->table[0]));
 
   for (tp = table; tp < table + size; tp += (2 * addr_size + 8), ++tep)
     {
@@ -4904,6 +4981,7 @@ slurp_hppa_unwind_table (FILE *file,
        ++relsec)
     {
       if (relsec->sh_type != SHT_RELA
+	  || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
 	  || SECTION_HEADER (relsec->sh_info) != sec)
 	continue;
 
@@ -4968,20 +5046,23 @@ hppa_process_unwind (FILE *file)
 
   memset (& aux, 0, sizeof (aux));
 
-  assert (string_table != NULL);
+  if (string_table == NULL)
+    return 1;
+
   addr_size = is_32bit_elf ? 4 : 8;
 
   for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
     {
-      if (sec->sh_type == SHT_SYMTAB)
+      if (sec->sh_type == SHT_SYMTAB
+	  && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
 	{
 	  aux.nsyms = sec->sh_size / sec->sh_entsize;
 	  aux.symtab = GET_ELF_SYMBOLS (file, sec);
 
 	  strsec = SECTION_HEADER (sec->sh_link);
-	  aux.strtab_size = strsec->sh_size;
 	  aux.strtab = get_data (NULL, file, strsec->sh_offset,
-				 aux.strtab_size, _("string table"));
+				 1, strsec->sh_size, _("string table"));
+	  aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
 	}
       else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
 	unwsec = sec;
@@ -5197,7 +5278,7 @@ get_32bit_dynamic_section (FILE *file)
   Elf32_External_Dyn *edyn, *ext;
   Elf_Internal_Dyn *entry;
 
-  edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
+  edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
 		   _("dynamic section"));
   if (!edyn)
     return 0;
@@ -5214,7 +5295,7 @@ get_32bit_dynamic_section (FILE *file)
 	break;
     }
 
-  dynamic_section = malloc (dynamic_nent * sizeof (*entry));
+  dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
   if (dynamic_section == NULL)
     {
       error (_("Out of memory\n"));
@@ -5241,7 +5322,7 @@ get_64bit_dynamic_section (FILE *file)
   Elf64_External_Dyn *edyn, *ext;
   Elf_Internal_Dyn *entry;
 
-  edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
+  edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
 		   _("dynamic section"));
   if (!edyn)
     return 0;
@@ -5258,7 +5339,7 @@ get_64bit_dynamic_section (FILE *file)
 	break;
     }
 
-  dynamic_section = malloc (dynamic_nent * sizeof (*entry));
+  dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
   if (dynamic_section == NULL)
     {
       error (_("Out of memory\n"));
@@ -5418,7 +5499,7 @@ process_dynamic_section (FILE *file)
 	      continue;
 	    }
 
-	  dynamic_strings = get_data (NULL, file, offset, str_tab_len,
+	  dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
 				      _("dynamic string table"));
 	  dynamic_strings_length = str_tab_len;
 	  break;
@@ -5453,8 +5534,8 @@ process_dynamic_section (FILE *file)
 	  Elf_Internal_Syminfo *syminfo;
 
 	  /* There is a syminfo section.  Read the data.  */
-	  extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, syminsz,
-				 _("symbol information"));
+	  extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
+				 syminsz, _("symbol information"));
 	  if (!extsyminfo)
 	    return 0;
 
@@ -5930,9 +6011,13 @@ process_version_sections (FILE *file)
 	    printf_vma (section->sh_addr);
 	    printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
 		    (unsigned long) section->sh_offset, section->sh_link,
-		    SECTION_NAME (SECTION_HEADER (section->sh_link)));
+		    SECTION_HEADER_INDEX (section->sh_link)
+		    < elf_header.e_shnum
+		    ? SECTION_NAME (SECTION_HEADER (section->sh_link))
+		    : "<corrupt>");
 
-	    edefs = get_data (NULL, file, section->sh_offset, section->sh_size,
+	    edefs = get_data (NULL, file, section->sh_offset, 1,
+			      section->sh_size,
 			      _("version definition section"));
 	    if (!edefs)
 	      break;
@@ -6019,9 +6104,13 @@ process_version_sections (FILE *file)
 	    printf_vma (section->sh_addr);
 	    printf (_("  Offset: %#08lx  Link to section: %ld (%s)\n"),
 		    (unsigned long) section->sh_offset, section->sh_link,
-		    SECTION_NAME (SECTION_HEADER (section->sh_link)));
+		    SECTION_HEADER_INDEX (section->sh_link)
+		    < elf_header.e_shnum
+		    ? SECTION_NAME (SECTION_HEADER (section->sh_link))
+		    : "<corrupt>");
 
-	    eneed = get_data (NULL, file, section->sh_offset, section->sh_size,
+	    eneed = get_data (NULL, file, section->sh_offset, 1,
+			      section->sh_size,
 			      _("version need section"));
 	    if (!eneed)
 	      break;
@@ -6101,16 +6190,23 @@ process_version_sections (FILE *file)
 	    Elf_Internal_Shdr *string_sec;
 	    long off;
 
+	    if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
+	      break;
+
 	    link_section = SECTION_HEADER (section->sh_link);
 	    total = section->sh_size / section->sh_entsize;
 
+	    if (SECTION_HEADER_INDEX (link_section->sh_link)
+		>= elf_header.e_shnum)
+	      break;
+
 	    found = 1;
 
 	    symbols = GET_ELF_SYMBOLS (file, link_section);
 
 	    string_sec = SECTION_HEADER (link_section->sh_link);
 
-	    strtab = get_data (NULL, file, string_sec->sh_offset,
+	    strtab = get_data (NULL, file, string_sec->sh_offset, 1,
 			       string_sec->sh_size, _("version string table"));
 	    if (!strtab)
 	      break;
@@ -6127,7 +6223,7 @@ process_version_sections (FILE *file)
 	    off = offset_from_vma (file,
 				   version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
 				   total * sizeof (short));
-	    edata = get_data (NULL, file, off, total * sizeof (short),
+	    edata = get_data (NULL, file, off, total, sizeof (short),
 			      _("version symbol data"));
 	    if (!edata)
 	      {
@@ -6135,7 +6231,7 @@ process_version_sections (FILE *file)
 		break;
 	      }
 
-	    data = malloc (total * sizeof (short));
+	    data = cmalloc (total, sizeof (short));
 
 	    for (cnt = total; cnt --;)
 	      data[cnt] = byte_get (edata + cnt * sizeof (short),
@@ -6168,8 +6264,10 @@ process_version_sections (FILE *file)
 
 		      check_def = 1;
 		      check_need = 1;
-		      if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
-			  != SHT_NOBITS)
+		      if (SECTION_HEADER_INDEX (symbols[cnt + j].st_shndx)
+			  >= elf_header.e_shnum
+			  || SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
+			     != SHT_NOBITS)
 			{
 			  if (symbols[cnt + j].st_shndx == SHN_UNDEF)
 			    check_def = 0;
@@ -6194,7 +6292,7 @@ process_version_sections (FILE *file)
 			      Elf_External_Vernaux evna;
 			      unsigned long a_off;
 
-			      get_data (&evn, file, offset, sizeof (evn),
+			      get_data (&evn, file, offset, sizeof (evn), 1,
 					_("version need"));
 
 			      ivn.vn_aux  = BYTE_GET (evn.vn_aux);
@@ -6205,7 +6303,7 @@ process_version_sections (FILE *file)
 			      do
 				{
 				  get_data (&evna, file, a_off, sizeof (evna),
-					    _("version need aux (2)"));
+					    1, _("version need aux (2)"));
 
 				  ivna.vna_next  = BYTE_GET (evna.vna_next);
 				  ivna.vna_other = BYTE_GET (evna.vna_other);
@@ -6246,7 +6344,7 @@ process_version_sections (FILE *file)
 
 			  do
 			    {
-			      get_data (&evd, file, offset, sizeof (evd),
+			      get_data (&evd, file, offset, sizeof (evd), 1,
 					_("version def"));
 
 			      ivd.vd_next = BYTE_GET (evd.vd_next);
@@ -6266,7 +6364,8 @@ process_version_sections (FILE *file)
 
 			      get_data (&evda, file,
 					offset - ivd.vd_next + ivd.vd_aux,
-					sizeof (evda), _("version def aux"));
+					sizeof (evda), 1,
+					_("version def aux"));
 
 			      ivda.vda_name = BYTE_GET (evda.vda_name);
 
@@ -6417,7 +6516,7 @@ get_dynamic_data (FILE *file, unsigned i
   unsigned char *e_data;
   int *i_data;
 
-  e_data = malloc (number * 4);
+  e_data = cmalloc (number, 4);
 
   if (e_data == NULL)
     {
@@ -6431,7 +6530,7 @@ get_dynamic_data (FILE *file, unsigned i
       return NULL;
     }
 
-  i_data = malloc (number * sizeof (*i_data));
+  i_data = cmalloc (number, sizeof (*i_data));
 
   if (i_data == NULL)
     {
@@ -6547,7 +6646,8 @@ process_symbol_table (FILE *file)
 	   i++, section++)
 	{
 	  unsigned int si;
-	  char *strtab;
+	  char *strtab = NULL;
+	  unsigned long int strtab_size = 0;
 	  Elf_Internal_Sym *symtab;
 	  Elf_Internal_Sym *psym;
 
@@ -6569,15 +6669,19 @@ process_symbol_table (FILE *file)
 	    continue;
 
 	  if (section->sh_link == elf_header.e_shstrndx)
-	    strtab = string_table;
-	  else
+	    {
+	      strtab = string_table;
+	      strtab_size = string_table_length;
+	    }
+	  else if (SECTION_HEADER_INDEX (section->sh_link) < elf_header.e_shnum)
 	    {
 	      Elf_Internal_Shdr *string_sec;
 
 	      string_sec = SECTION_HEADER (section->sh_link);
 
 	      strtab = get_data (NULL, file, string_sec->sh_offset,
-				 string_sec->sh_size, _("string table"));
+				 1, string_sec->sh_size, _("string table"));
+	      strtab_size = strtab != NULL ? string_sec->sh_size : 0;
 	    }
 
 	  for (si = 0, psym = symtab;
@@ -6592,7 +6696,8 @@ process_symbol_table (FILE *file)
 	      printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
 	      printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
 	      printf (" %4s ", get_symbol_index_type (psym->st_shndx));
-	      print_symbol (25, strtab + psym->st_name);
+	      print_symbol (25, psym->st_name < strtab_size
+			    ? strtab + psym->st_name : "<corrupt>");
 
 	      if (section->sh_type == SHT_DYNSYM &&
 		  version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
@@ -6608,12 +6713,14 @@ process_symbol_table (FILE *file)
 		     sizeof data + si * sizeof (vers_data));
 
 		  get_data (&data, file, offset + si * sizeof (vers_data),
-			    sizeof (data), _("version data"));
+			    sizeof (data), 1, _("version data"));
 
 		  vers_data = byte_get (data, 2);
 
-		  is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
-			       == SHT_NOBITS);
+		  is_nobits = (SECTION_HEADER_INDEX (psym->st_shndx)
+			       < elf_header.e_shnum
+			       && SECTION_HEADER (psym->st_shndx)->sh_type
+				  == SHT_NOBITS);
 
 		  check_def = (psym->st_shndx != SHN_UNDEF);
 
@@ -6635,7 +6742,7 @@ process_symbol_table (FILE *file)
 			    {
 			      unsigned long vna_off;
 
-			      get_data (&evn, file, offset, sizeof (evn),
+			      get_data (&evn, file, offset, sizeof (evn), 1,
 					_("version need"));
 
 			      ivn.vn_aux  = BYTE_GET (evn.vn_aux);
@@ -6648,7 +6755,7 @@ process_symbol_table (FILE *file)
 				  Elf_External_Vernaux evna;
 
 				  get_data (&evna, file, vna_off,
-					    sizeof (evna),
+					    sizeof (evna), 1,
 					    _("version need aux (3)"));
 
 				  ivna.vna_other = BYTE_GET (evna.vna_other);
@@ -6670,7 +6777,9 @@ process_symbol_table (FILE *file)
 			  if (ivna.vna_other == vers_data)
 			    {
 			      printf ("@%s (%d)",
-				      strtab + ivna.vna_name, ivna.vna_other);
+				      ivna.vna_name < strtab_size
+				      ? strtab + ivna.vna_name : "<corrupt>",
+				      ivna.vna_other);
 			      check_def = 0;
 			    }
 			  else if (! is_nobits)
@@ -6699,7 +6808,7 @@ process_symbol_table (FILE *file)
 				  Elf_External_Verdef evd;
 
 				  get_data (&evd, file, offset, sizeof (evd),
-					    _("version def"));
+					    1, _("version def"));
 
 				  ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
 				  ivd.vd_aux = BYTE_GET (evd.vd_aux);
@@ -6714,14 +6823,15 @@ process_symbol_table (FILE *file)
 			      offset += ivd.vd_aux;
 
 			      get_data (&evda, file, offset, sizeof (evda),
-					_("version def aux"));
+					1, _("version def aux"));
 
 			      ivda.vda_name = BYTE_GET (evda.vda_name);
 
 			      if (psym->st_name != ivda.vda_name)
 				printf ((vers_data & 0x8000)
 					? "@%s" : "@@%s",
-					strtab + ivda.vda_name);
+					ivda.vda_name < strtab_size
+					? strtab + ivda.vda_name : "<corrupt>");
 			    }
 			}
 		    }
@@ -6908,7 +7018,8 @@ dump_section (Elf_Internal_Shdr *section
 
   addr = section->sh_addr;
 
-  start = get_data (NULL, file, section->sh_offset, bytes, _("section data"));
+  start = get_data (NULL, file, section->sh_offset, 1, bytes,
+		    _("section data"));
   if (!start)
     return 0;
 
@@ -7164,7 +7275,7 @@ get_debug_info (FILE * file)
     return 0;
 
   length = section->sh_size;
-  start = get_data (NULL, file, section->sh_offset, section->sh_size,
+  start = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
 		    _("extracting information from .debug_info section"));
   if (start == NULL)
     return 0;
@@ -7195,7 +7306,7 @@ get_debug_info (FILE * file)
     }
 
   /* Then allocate an array to hold the information.  */
-  debug_information = malloc (num_units * sizeof * debug_information);
+  debug_information = cmalloc (num_units, sizeof * debug_information);
   if (debug_information == NULL)
     {
       error (_("Not enough memory for a debug info array of %u entries"),
@@ -8482,7 +8593,7 @@ load_debug_loc (FILE *file)
 
   debug_loc_size = sec->sh_size;
 
-  debug_loc_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+  debug_loc_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
 				 _("debug_loc section data"));
 }
 
@@ -8593,7 +8704,7 @@ load_debug_str (FILE *file)
 
   debug_str_size = sec->sh_size;
 
-  debug_str_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+  debug_str_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
 				 _("debug_str section data"));
 }
 
@@ -8698,7 +8809,7 @@ load_debug_range (FILE *file)
 
   debug_range_size = sec->sh_size;
 
-  debug_range_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+  debug_range_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
 				   _("debug_range section data"));
 }
 
@@ -9217,8 +9328,10 @@ debug_apply_rela_addends (FILE *file,
       Elf_Internal_Sym *sym;
 
       if (relsec->sh_type != SHT_RELA
+	  || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
 	  || SECTION_HEADER (relsec->sh_info) != section
-	  || relsec->sh_size == 0)
+	  || relsec->sh_size == 0
+	  || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
 	continue;
 
       if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
@@ -9370,7 +9483,7 @@ display_debug_info (Elf_Internal_Shdr *s
 	    return 0;
 	  }
 
-	begin = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+	begin = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
 			  _("debug_abbrev section data"));
 	if (!begin)
 	  return 0;
@@ -9660,8 +9773,8 @@ frame_need_space (Frame_Chunk *fc, int r
     return;
 
   fc->ncols = reg + 1;
-  fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int));
-  fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int));
+  fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int));
+  fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
 
   while (prev < fc->ncols)
     {
@@ -9972,8 +10085,8 @@ display_debug_frames (Elf_Internal_Shdr 
 	  else
 	    {
 	      fc->ncols = cie->ncols;
-	      fc->col_type = xmalloc (fc->ncols * sizeof (short int));
-	      fc->col_offset = xmalloc (fc->ncols * sizeof (int));
+	      fc->col_type = xcmalloc (fc->ncols, sizeof (short int));
+	      fc->col_offset = xcmalloc (fc->ncols, sizeof (int));
 	      memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
 	      memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
 	      fc->augmentation = cie->augmentation;
@@ -10284,8 +10397,8 @@ display_debug_frames (Elf_Internal_Shdr 
 		printf ("  DW_CFA_remember_state\n");
 	      rs = xmalloc (sizeof (Frame_Chunk));
 	      rs->ncols = fc->ncols;
-	      rs->col_type = xmalloc (rs->ncols * sizeof (short int));
-	      rs->col_offset = xmalloc (rs->ncols * sizeof (int));
+	      rs->col_type = xcmalloc (rs->ncols, sizeof (short int));
+	      rs->col_offset = xcmalloc (rs->ncols, sizeof (int));
 	      memcpy (rs->col_type, fc->col_type, rs->ncols);
 	      memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
 	      rs->next = remembered_state;
@@ -10505,7 +10618,7 @@ display_debug_section (Elf_Internal_Shdr
       {
 	unsigned char *start;
 
-	start = get_data (NULL, file, section->sh_offset, length,
+	start = get_data (NULL, file, section->sh_offset, 1, length,
 			  _("debug section data"));
 	if (start == NULL)
 	  {
@@ -10631,7 +10744,7 @@ process_mips_specific (FILE *file)
       size_t cnt;
 
       elib = get_data (NULL, file, liblist_offset,
-		       liblistno * sizeof (Elf32_External_Lib),
+		       liblistno, sizeof (Elf32_External_Lib),
 		       _("liblist"));
       if (elib)
 	{
@@ -10719,11 +10832,11 @@ process_mips_specific (FILE *file)
       while (sect->sh_type != SHT_MIPS_OPTIONS)
 	++sect;
 
-      eopt = get_data (NULL, file, options_offset, sect->sh_size,
+      eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
 		       _("options"));
       if (eopt)
 	{
-	  iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt));
+	  iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt));
 	  if (iopt == NULL)
 	    {
 	      error (_("Out of memory"));
@@ -10915,7 +11028,7 @@ process_mips_specific (FILE *file)
 	  return 0;
 	}
 
-      iconf = malloc (conflictsno * sizeof (*iconf));
+      iconf = cmalloc (conflictsno, sizeof (*iconf));
       if (iconf == NULL)
 	{
 	  error (_("Out of memory"));
@@ -10927,7 +11040,7 @@ process_mips_specific (FILE *file)
 	  Elf32_External_Conflict *econf32;
 
 	  econf32 = get_data (NULL, file, conflicts_offset,
-			      conflictsno * sizeof (*econf32), _("conflict"));
+			      conflictsno, sizeof (*econf32), _("conflict"));
 	  if (!econf32)
 	    return 0;
 
@@ -10941,7 +11054,7 @@ process_mips_specific (FILE *file)
 	  Elf64_External_Conflict *econf64;
 
 	  econf64 = get_data (NULL, file, conflicts_offset,
-			      conflictsno * sizeof (*econf64), _("conflict"));
+			      conflictsno, sizeof (*econf64), _("conflict"));
 	  if (!econf64)
 	    return 0;
 
@@ -10981,6 +11094,7 @@ process_gnu_liblist (FILE *file)
   Elf_Internal_Shdr *section, *string_sec;
   Elf32_External_Lib *elib;
   char *strtab;
+  size_t strtab_size;
   size_t cnt;
   unsigned i;
 
@@ -10994,15 +11108,19 @@ process_gnu_liblist (FILE *file)
       switch (section->sh_type)
 	{
 	case SHT_GNU_LIBLIST:
-	  elib = get_data (NULL, file, section->sh_offset, section->sh_size,
+	  if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
+	    break;
+
+	  elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
 			   _("liblist"));
 
 	  if (elib == NULL)
 	    break;
 	  string_sec = SECTION_HEADER (section->sh_link);
 
-	  strtab = get_data (NULL, file, string_sec->sh_offset,
+	  strtab = get_data (NULL, file, string_sec->sh_offset, 1,
 			     string_sec->sh_size, _("liblist string table"));
+	  strtab_size = string_sec->sh_size;
 
 	  if (strtab == NULL
 	      || section->sh_entsize != sizeof (Elf32_External_Lib))
@@ -11038,9 +11156,11 @@ process_gnu_liblist (FILE *file)
 
 	      printf ("%3lu: ", (unsigned long) cnt);
 	      if (do_wide)
-		printf ("%-20s", strtab + liblist.l_name);
+		printf ("%-20s", liblist.l_name < strtab_size
+				 ? strtab + liblist.l_name : "<corrupt>");
 	      else
-		printf ("%-20.20s", strtab + liblist.l_name);
+		printf ("%-20.20s", liblist.l_name < strtab_size
+				    ? strtab + liblist.l_name : "<corrupt>");
 	      printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
 		      liblist.l_version, liblist.l_flags);
 	    }
@@ -11204,7 +11324,7 @@ process_corefile_note_segment (FILE *fil
   if (length <= 0)
     return 0;
 
-  pnotes = get_data (NULL, file, offset, length, _("notes"));
+  pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
   if (!pnotes)
     return 0;
 

binutils-2.15.94.0.2-robustify4.patch:
 bfd-in.h       |    3 
 bfd-in2.h      |    3 
 elf.c          |  176 ++++++++++++++++++++++++++++++++++++++-------------------
 elf32-s390.c   |   12 ++-
 elf32-sparc.c  |   12 ++-
 elf64-ppc.c    |    9 ++
 elf64-s390.c   |   12 ++-
 elf64-sparc.c  |   10 ++-
 elf64-x86-64.c |   15 ++--
 elfxx-ia64.c   |    3 
 libbfd-in.h    |   10 +++
 libbfd.c       |  102 +++++++++++++++++++++++++++++++++
 libbfd.h       |   10 +++
 opncls.c       |   48 +++++++++++++++
 14 files changed, 349 insertions(+), 76 deletions(-)

--- NEW FILE binutils-2.15.94.0.2-robustify4.patch ---
2005-06-15  Jakub Jelinek  <jakub redhat com>

	* libbfd-in.h (bfd_malloc2, bfd_realloc2, bfd_zmalloc2, bfd_alloc2,
	bfd_zalloc2): New prototypes.
	* bfd-in.h (HALF_BFD_SIZE_TYPE): Define.
	* libbfd.c (bfd_malloc2, bfd_realloc2, bfd_zmalloc2): New functions.
	* opncls.c (bfd_alloc2, bfd_zalloc2): New functions.
	* elf.c (bfd_elf_get_elf_syms, setup_group, assign_section_numbers,
	elf_map_symbols, map_sections_to_segments,
	assign_file_positions_for_segments, copy_private_bfd_data,
	swap_out_syms, _bfd_elf_slurp_version_tables): Use bfd_*alloc2
	where appropriate.
	* bfd-in2.h: Rebuilt.
	* libbfd.h: Rebuilt.

	* elf.c (_bfd_elf_print_private_bfd_data): Don't crash on bogus
	verdef or verneed section.
	(_bfd_elf_slurp_version_tables): Handle corrupt verdef and/or
	verneed sections gracefully.
	* elf32-sparc.c (elf32_sparc_info_to_howto): Don't crash on
	bogus relocation values.
	* elf64-sparc.c (sparc64_elf_info_to_howto): Likewise.
	* elf64-ppc.c (ppc64_elf_info_to_howto): Likewise.
	* elf64-s390.c (elf_s390_info_to_howto): Likewise.
	* elf32-s390.c (elf_s390_info_to_howto): Likewise.
	* elf64-x86-64.c (elf64_x86_64_info_to_howto): Likewise.
	* elfxx-ia64.c (lookup_howto): Likewise.

--- bfd/libbfd-in.h.jj	2004-11-22 15:33:31.000000000 -0500
+++ bfd/libbfd-in.h	2005-06-29 04:37:50.000000000 -0400
@@ -90,6 +90,12 @@ extern void *bfd_realloc
   (void *, bfd_size_type);
 extern void *bfd_zmalloc
   (bfd_size_type);
+extern void *bfd_malloc2
+  (bfd_size_type, bfd_size_type);
+extern void *bfd_realloc2
+  (void *, bfd_size_type, bfd_size_type);
+extern void *bfd_zmalloc2
+  (bfd_size_type, bfd_size_type);
 
 extern void _bfd_default_error_handler (const char *s, ...);
 extern bfd_error_handler_type _bfd_error_handler;
@@ -100,6 +106,10 @@ extern void *bfd_alloc
   (bfd *, bfd_size_type);
 extern void *bfd_zalloc
   (bfd *, bfd_size_type);
+extern void *bfd_alloc2
+  (bfd *, bfd_size_type, bfd_size_type);
+extern void *bfd_zalloc2
+  (bfd *, bfd_size_type, bfd_size_type);
 extern void bfd_release
   (bfd *, void *);
 
--- bfd/bfd-in.h.jj	2004-12-20 14:16:48.000000000 -0500
+++ bfd/bfd-in.h	2005-06-29 04:37:50.000000000 -0400
@@ -144,6 +144,9 @@ typedef unsigned long bfd_size_type;
 
 #endif /* not BFD64  */
 
+#define HALF_BFD_SIZE_TYPE \
+  (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
+
 #ifndef BFD_HOST_64_BIT
 /* Fall back on a 32 bit type.  The idea is to make these types always
    available for function return types, but in the case that
--- bfd/libbfd.c.jj	2004-09-15 15:05:03.000000000 -0400
+++ bfd/libbfd.c	2005-06-29 04:37:50.000000000 -0400
@@ -156,6 +156,36 @@ bfd_malloc (bfd_size_type size)
   return ptr;
 }
 
+/* Allocate memory using malloc, nmemb * size with overflow checking.  */
+
+void *
+bfd_malloc2 (bfd_size_type nmemb, bfd_size_type size)
+{
+  void *ptr;
+
+  if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+      && size != 0
+      && nmemb > ~(bfd_size_type) 0 / size)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return NULL;
+    }
+
+  size *= nmemb;
+
+  if (size != (size_t) size)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return NULL;
+    }
+
+  ptr = malloc ((size_t) size);
+  if (ptr == NULL && (size_t) size != 0)
+    bfd_set_error (bfd_error_no_memory);
+
+  return ptr;
+}
+
 /* Reallocate memory using realloc.  */
 
 void *
@@ -180,6 +210,40 @@ bfd_realloc (void *ptr, bfd_size_type si
   return ret;
 }
 
+/* Reallocate memory using realloc, nmemb * size with overflow checking.  */
+
+void *
+bfd_realloc2 (void *ptr, bfd_size_type nmemb, bfd_size_type size)
+{
+  void *ret;
+
+  if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+      && size != 0
+      && nmemb > ~(bfd_size_type) 0 / size)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return NULL;
+    }
+
+  size *= nmemb;
+
+  if (size != (size_t) size)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return NULL;
+    }
+
+  if (ptr == NULL)
+    ret = malloc ((size_t) size);
+  else
+    ret = realloc (ptr, (size_t) size);
+
+  if (ret == NULL && (size_t) size != 0)
+    bfd_set_error (bfd_error_no_memory);
+
+  return ret;
+}
+
 /* Allocate memory using malloc and clear it.  */
 
 void *
@@ -205,6 +269,44 @@ bfd_zmalloc (bfd_size_type size)
 
   return ptr;
 }
+
+/* Allocate memory using malloc (nmemb * size) with overflow checking
+   and clear it.  */
+
+void *
+bfd_zmalloc2 (bfd_size_type nmemb, bfd_size_type size)
+{
+  void *ptr;
+
+  if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+      && size != 0
+      && nmemb > ~(bfd_size_type) 0 / size)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return NULL;
+    }
+
+  size *= nmemb;
+
+  if (size != (size_t) size)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return NULL;
+    }
+
+  ptr = malloc ((size_t) size);
+
+  if ((size_t) size != 0)
+    {
+      if (ptr == NULL)
+	bfd_set_error (bfd_error_no_memory);
+      else
+	memset (ptr, 0, (size_t) size);
+    }
+
+  return ptr;
+}
+
 /*
 INTERNAL_FUNCTION
 	bfd_write_bigendian_4byte_int
--- bfd/opncls.c.jj	2004-11-22 15:33:31.000000000 -0500
+++ bfd/opncls.c	2005-06-29 04:41:50.000000000 -0400
@@ -849,6 +849,54 @@ bfd_zalloc (bfd *abfd, bfd_size_type siz
   return res;
 }
 
+void *
+bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
+{
+  void *ret;
+
+  if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+      && size != 0
+      && nmemb > ~(bfd_size_type) 0 / size)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return NULL;
+    }
+
+  size *= nmemb;
+
+  if (size != (unsigned long) size)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return NULL;
+    }
+
+  ret = objalloc_alloc (abfd->memory, (unsigned long) size);
+  if (ret == NULL)
+    bfd_set_error (bfd_error_no_memory);
+  return ret;
+}
+
+void *
+bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
+{
+  void *res;
+
+  if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+      && size != 0
+      && nmemb > ~(bfd_size_type) 0 / size)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return NULL;
+    }
+
+  size *= nmemb;
+
+  res = bfd_alloc (abfd, size);
+  if (res)
+    memset (res, 0, (size_t) size);
+  return res;
+}
+
 /* Free a block allocated for a BFD.
    Note:  Also frees all more recently allocated blocks!  */
 
--- bfd/elf.c.jj	2005-06-29 04:36:58.000000000 -0400
+++ bfd/elf.c	2005-06-29 04:46:03.000000000 -0400
@@ -340,7 +340,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
   pos = symtab_hdr->sh_offset + symoffset * extsym_size;
   if (extsym_buf == NULL)
     {
-      alloc_ext = bfd_malloc (amt);
+      alloc_ext = bfd_malloc2 (symcount, extsym_size);
       extsym_buf = alloc_ext;
     }
   if (extsym_buf == NULL
@@ -359,7 +359,8 @@ bfd_elf_get_elf_syms (bfd *ibfd,
       pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
       if (extshndx_buf == NULL)
 	{
-	  alloc_extshndx = bfd_malloc (amt);
+	  alloc_extshndx = bfd_malloc2 (symcount,
+					sizeof (Elf_External_Sym_Shndx));
 	  extshndx_buf = alloc_extshndx;
 	}
       if (extshndx_buf == NULL
@@ -373,8 +374,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
 
   if (intsym_buf == NULL)
     {
-      bfd_size_type amt = symcount * sizeof (Elf_Internal_Sym);
-      intsym_buf = bfd_malloc (amt);
+      intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
       if (intsym_buf == NULL)
 	goto out;
     }
@@ -483,8 +483,10 @@ setup_group (bfd *abfd, Elf_Internal_Shd
 	{
 	  /* We keep a list of elf section headers for group sections,
 	     so we can find them quickly.  */
-	  bfd_size_type amt = num_group * sizeof (Elf_Internal_Shdr *);
-	  elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, amt);
+  	     so we can find them quickly.  */
+	  bfd_size_type amt;
+	  elf_tdata (abfd)->group_sect_ptr
+	    = bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
 	  if (elf_tdata (abfd)->group_sect_ptr == NULL)
 	    return FALSE;
 
@@ -504,7 +506,8 @@ setup_group (bfd *abfd, Elf_Internal_Shd
 		  /* Read the raw contents.  */
 		  BFD_ASSERT (sizeof (*dest) >= 4);
 		  amt = shdr->sh_size * sizeof (*dest) / 4;
-		  shdr->contents = bfd_alloc (abfd, amt);
+		  shdr->contents = bfd_alloc2 (abfd, shdr->sh_size,
+					       sizeof (*dest) / 4);
 		  if (shdr->contents == NULL
 		      || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
 		      || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
@@ -1207,8 +1210,9 @@ _bfd_elf_print_private_bfd_data (bfd *ab
       for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
 	{
 	  fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
-		   t->vd_flags, t->vd_hash, t->vd_nodename);
-	  if (t->vd_auxptr->vda_nextptr != NULL)
+		   t->vd_flags, t->vd_hash,
+		   t->vd_nodename ? t->vd_nodename : "<corrupt>");
+	  if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL)
 	    {
 	      Elf_Internal_Verdaux *a;
 
@@ -1216,7 +1220,8 @@ _bfd_elf_print_private_bfd_data (bfd *ab
 	      for (a = t->vd_auxptr->vda_nextptr;
 		   a != NULL;
 		   a = a->vda_nextptr)
-		fprintf (f, "%s ", a->vda_nodename);
+		fprintf (f, "%s ",
+			 a->vda_nodename ? a->vda_nodename : "<corrupt>");
 	      fprintf (f, "\n");
 	    }
 	}
@@ -1231,10 +1236,12 @@ _bfd_elf_print_private_bfd_data (bfd *ab
 	{
 	  Elf_Internal_Vernaux *a;
 
-	  fprintf (f, _("  required from %s:\n"), t->vn_filename);
+	  fprintf (f, _("  required from %s:\n"),
+		   t->vn_filename ? t->vn_filename : "<corrupt>");
 	  for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
 	    fprintf (f, "    0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
-		     a->vna_flags, a->vna_other, a->vna_nodename);
+		     a->vna_flags, a->vna_other,
+		     a->vna_nodename ? a->vna_nodename : "<corrupt>");
 	}
     }
 
@@ -2760,7 +2767,6 @@ assign_section_numbers (bfd *abfd)
   asection *sec;
   unsigned int section_number, secn;
   Elf_Internal_Shdr **i_shdrp;
-  bfd_size_type amt;
   struct bfd_elf_section_data *d;
 
   section_number = 1;
@@ -2851,13 +2857,11 @@ assign_section_numbers (bfd *abfd)
 
   /* Set up the list of section header pointers, in agreement with the
      indices.  */
-  amt = section_number * sizeof (Elf_Internal_Shdr *);
-  i_shdrp = bfd_zalloc (abfd, amt);
+  i_shdrp = bfd_zalloc2 (abfd, section_number, sizeof (Elf_Internal_Shdr *));
   if (i_shdrp == NULL)
     return FALSE;
 
-  amt = sizeof (Elf_Internal_Shdr);
-  i_shdrp[0] = bfd_zalloc (abfd, amt);
+  i_shdrp[0] = bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr));
   if (i_shdrp[0] == NULL)
     {
       bfd_release (abfd, i_shdrp);
@@ -3089,7 +3093,6 @@ elf_map_symbols (bfd *abfd)
   unsigned int idx;
   asection *asect;
   asymbol **new_syms;
-  bfd_size_type amt;
 
 #ifdef DEBUG
   fprintf (stderr, "elf_map_symbols\n");
@@ -3103,8 +3106,7 @@ elf_map_symbols (bfd *abfd)
     }
 
   max_index++;
-  amt = max_index * sizeof (asymbol *);
-  sect_syms = bfd_zalloc (abfd, amt);
+  sect_syms = bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
   if (sect_syms == NULL)
     return FALSE;
   elf_section_syms (abfd) = sect_syms;
@@ -3177,8 +3179,7 @@ elf_map_symbols (bfd *abfd)
     }
 
   /* Now sort the symbols so the local symbols are first.  */
-  amt = (num_locals + num_globals) * sizeof (asymbol *);
-  new_syms = bfd_alloc (abfd, amt);
+  new_syms = bfd_alloc2 (abfd, num_locals + num_globals, sizeof (asymbol *));
 
   if (new_syms == NULL)
     return FALSE;
@@ -3437,8 +3438,7 @@ map_sections_to_segments (bfd *abfd)
 
   /* Select the allocated sections, and sort them.  */
 
-  amt = bfd_count_sections (abfd) * sizeof (asection *);
-  sections = bfd_malloc (amt);
+  sections = bfd_malloc2 (bfd_count_sections (abfd), sizeof (asection *));
   if (sections == NULL)
     goto error_return;
 
@@ -3870,7 +3870,6 @@ assign_file_positions_for_segments (bfd 
   bfd_vma filehdr_vaddr, filehdr_paddr;
   bfd_vma phdrs_vaddr, phdrs_paddr;
   Elf_Internal_Phdr *p;
-  bfd_size_type amt;
 
   if (elf_tdata (abfd)->segment_map == NULL)
     {
@@ -3945,8 +3944,7 @@ assign_file_positions_for_segments (bfd 
   if (alloc == 0)
     alloc = count;
 
-  amt = alloc * sizeof (Elf_Internal_Phdr);
-  phdrs = bfd_alloc (abfd, amt);
+  phdrs = bfd_alloc2 (abfd, alloc, sizeof (Elf_Internal_Phdr));
   if (phdrs == NULL)
     return FALSE;
 
@@ -5214,8 +5212,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *o
 
       /* Gcc 2.96 miscompiles this code on mips. Don't do casting here
 	 to work around this long long bug.  */
-      amt = section_count * sizeof (asection *);
-      sections = bfd_malloc (amt);
+      sections = bfd_malloc2 (section_count, sizeof (asection *));
       if (sections == NULL)
 	return FALSE;
 
@@ -5657,8 +5654,7 @@ swap_out_syms (bfd *abfd,
   symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
   symstrtab_hdr->sh_type = SHT_STRTAB;
 
-  amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym;
-  outbound_syms = bfd_alloc (abfd, amt);
+  outbound_syms = bfd_alloc2 (abfd, 1 + symcount, bed->s->sizeof_sym);
   if (outbound_syms == NULL)
     {
       _bfd_stringtab_free (stt);
@@ -5671,7 +5667,8 @@ swap_out_syms (bfd *abfd,
   if (symtab_shndx_hdr->sh_name != 0)
     {
       amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
-      outbound_shndx = bfd_zalloc (abfd, amt);
+      outbound_shndx = bfd_zalloc2 (abfd, 1 + symcount,
+				    sizeof (Elf_External_Sym_Shndx));
       if (outbound_shndx == NULL)
 	{
 	  _bfd_stringtab_free (stt);
@@ -6083,7 +6080,6 @@ bfd_boolean
 _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
 {
   bfd_byte *contents = NULL;
-  bfd_size_type amt;
   unsigned int freeidx = 0;
 
   if (elf_dynverref (abfd) != 0)
@@ -6092,11 +6088,12 @@ _bfd_elf_slurp_version_tables (bfd *abfd
       Elf_External_Verneed *everneed;
       Elf_Internal_Verneed *iverneed;
       unsigned int i;
+      bfd_byte *contents_end;
 
       hdr = &elf_tdata (abfd)->dynverref_hdr;
 
-      amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed);
-      elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt);
+      elf_tdata (abfd)->verref = bfd_zalloc2 (abfd, hdr->sh_info,
+					      sizeof (Elf_Internal_Verneed));
       if (elf_tdata (abfd)->verref == NULL)
 	goto error_return;
 
@@ -6104,11 +6101,22 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 
       contents = bfd_malloc (hdr->sh_size);
       if (contents == NULL)
-	goto error_return;
+	{
+error_return_verref:
+	  elf_tdata (abfd)->verref = NULL;
+	  elf_tdata (abfd)->cverrefs = 0;
+	  goto error_return;
+	}
       if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
 	  || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
-	goto error_return;
+	goto error_return_verref;
 
+      if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed))
+	goto error_return_verref;
+
+      BFD_ASSERT (sizeof (Elf_External_Verneed)
+		  == sizeof (Elf_External_Vernaux));
+      contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed);
       everneed = (Elf_External_Verneed *) contents;
       iverneed = elf_tdata (abfd)->verref;
       for (i = 0; i < hdr->sh_info; i++, iverneed++)
@@ -6125,11 +6133,21 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 	    bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
 					     iverneed->vn_file);
 	  if (iverneed->vn_filename == NULL)
-	    goto error_return;
+	    goto error_return_verref;
 
-	  amt = iverneed->vn_cnt;
-	  amt *= sizeof (Elf_Internal_Vernaux);
-	  iverneed->vn_auxptr = bfd_alloc (abfd, amt);
+	  if (iverneed->vn_cnt == 0)
+	    iverneed->vn_auxptr = NULL;
+	  else
+	    {
+	      iverneed->vn_auxptr = bfd_alloc2 (abfd, iverneed->vn_cnt,
+						sizeof (Elf_Internal_Vernaux));
+	      if (iverneed->vn_auxptr == NULL)
+		goto error_return_verref;
+	    }
+
+	  if (iverneed->vn_aux
+	      > (size_t) (contents_end - (bfd_byte *) everneed))
+	    goto error_return_verref;
 
 	  evernaux = ((Elf_External_Vernaux *)
 		      ((bfd_byte *) everneed + iverneed->vn_aux));
@@ -6142,13 +6160,17 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 		bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
 						 ivernaux->vna_name);
 	      if (ivernaux->vna_nodename == NULL)
-		goto error_return;
+		goto error_return_verref;
 
 	      if (j + 1 < iverneed->vn_cnt)
 		ivernaux->vna_nextptr = ivernaux + 1;
 	      else
 		ivernaux->vna_nextptr = NULL;
 
+	      if (ivernaux->vna_next
+		  > (size_t) (contents_end - (bfd_byte *) evernaux))
+		goto error_return_verref;
+
 	      evernaux = ((Elf_External_Vernaux *)
 			  ((bfd_byte *) evernaux + ivernaux->vna_next));
 
@@ -6161,6 +6183,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 	  else
 	    iverneed->vn_nextref = NULL;
 
+	  if (iverneed->vn_next
+	      > (size_t) (contents_end - (bfd_byte *) everneed))
+	    goto error_return_verref;
+
 	  everneed = ((Elf_External_Verneed *)
 		      ((bfd_byte *) everneed + iverneed->vn_next));
 	}
@@ -6178,6 +6204,7 @@ _bfd_elf_slurp_version_tables (bfd *abfd
       Elf_Internal_Verdef iverdefmem;
       unsigned int i;
       unsigned int maxidx;
+      bfd_byte *contents_end_def, *contents_end_aux;
 
       hdr = &elf_tdata (abfd)->dynverdef_hdr;
 
@@ -6188,6 +6215,16 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 	  || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
 	goto error_return;
 
+      if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef))
+	goto error_return;
+
+      BFD_ASSERT (sizeof (Elf_External_Verdef)
+		  >= sizeof (Elf_External_Verdaux));
+      contents_end_def = contents + hdr->sh_size
+			 - sizeof (Elf_External_Verdef);
+      contents_end_aux = contents + hdr->sh_size
+			 - sizeof (Elf_External_Verdaux);
+
       /* We know the number of entries in the section but not the maximum
 	 index.  Therefore we have to run through all entries and find
 	 the maximum.  */
@@ -6200,6 +6237,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 	  if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
 	    maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
 
+	  if (iverdefmem.vd_next
+	      > (size_t) (contents_end_def - (bfd_byte *) everdef))
+	    goto error_return;
+
 	  everdef = ((Elf_External_Verdef *)
 		     ((bfd_byte *) everdef + iverdefmem.vd_next));
 	}
@@ -6211,8 +6252,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 	  else
 	    freeidx = ++maxidx;
 	}
-      amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef);
-      elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt);
+      elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, maxidx,
+					      sizeof (Elf_Internal_Verdef));
       if (elf_tdata (abfd)->verdef == NULL)
 	goto error_return;
 
@@ -6228,15 +6269,32 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 
 	  _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
 
+	  if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
+	    {
+error_return_verdef:
+	      elf_tdata (abfd)->verdef = NULL;
+	      elf_tdata (abfd)->cverdefs = 0;
+	      goto error_return;
+	    }
+
 	  iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
 	  memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
 
 	  iverdef->vd_bfd = abfd;
 
-	  amt = (bfd_size_type) iverdef->vd_cnt * sizeof (Elf_Internal_Verdaux);
-	  iverdef->vd_auxptr = bfd_alloc (abfd, amt);
-	  if (iverdef->vd_auxptr == NULL)
-	    goto error_return;
+	  if (iverdef->vd_cnt == 0)
+	    iverdef->vd_auxptr = NULL;
+	  else
+	    {
+	      iverdef->vd_auxptr = bfd_alloc2 (abfd, iverdef->vd_cnt,
+					       sizeof (Elf_Internal_Verdaux));
+	      if (iverdef->vd_auxptr == NULL)
+		goto error_return_verdef;
+	    }
+
+	  if (iverdef->vd_aux
+	      > (size_t) (contents_end_aux - (bfd_byte *) everdef))
+	    goto error_return_verdef;
 
 	  everdaux = ((Elf_External_Verdaux *)
 		      ((bfd_byte *) everdef + iverdef->vd_aux));
@@ -6249,20 +6307,25 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 		bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
 						 iverdaux->vda_name);
 	      if (iverdaux->vda_nodename == NULL)
-		goto error_return;
+		goto error_return_verdef;
 
 	      if (j + 1 < iverdef->vd_cnt)
 		iverdaux->vda_nextptr = iverdaux + 1;
 	      else
 		iverdaux->vda_nextptr = NULL;
 
+	      if (iverdaux->vda_next
+		  > (size_t) (contents_end_aux - (bfd_byte *) everdaux))
+		goto error_return_verdef;
+
 	      everdaux = ((Elf_External_Verdaux *)
 			  ((bfd_byte *) everdaux + iverdaux->vda_next));
 	    }
 
-	  iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
+	  if (iverdef->vd_cnt)
+	    iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
 
-	  if (i + 1 < hdr->sh_info)
+	  if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
 	    iverdef->vd_nextdef = iverdef + 1;
 	  else
 	    iverdef->vd_nextdef = NULL;
@@ -6281,8 +6344,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd
       else
 	freeidx++;
 
-      amt = (bfd_size_type) freeidx * sizeof (Elf_Internal_Verdef);
-      elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt);
+      elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, freeidx,
+					      sizeof (Elf_Internal_Verdef));
       if (elf_tdata (abfd)->verdef == NULL)
 	goto error_return;
 
@@ -6306,10 +6369,11 @@ _bfd_elf_slurp_version_tables (bfd *abfd
 
       iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
       if (iverdef->vd_nodename == NULL)
-	goto error_return;
+	goto error_return_verdef;
       iverdef->vd_nextdef = NULL;
-      amt = (bfd_size_type) sizeof (Elf_Internal_Verdaux);
-      iverdef->vd_auxptr = bfd_alloc (abfd, amt);
+      iverdef->vd_auxptr = bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
+      if (iverdef->vd_auxptr == NULL)
+	goto error_return_verdef;
 
       iverdaux = iverdef->vd_auxptr;
       iverdaux->vda_nodename = iverdef->vd_nodename;
--- bfd/elf64-ppc.c.jj	2004-12-20 14:16:48.000000000 -0500
+++ bfd/elf64-ppc.c	2005-06-29 04:38:02.000000000 -0400
@@ -2118,8 +2118,13 @@ ppc64_elf_info_to_howto (bfd *abfd ATTRI
     ppc_howto_init ();
 
   type = ELF64_R_TYPE (dst->r_info);
-  BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table)
-		      / sizeof (ppc64_elf_howto_table[0])));
+  if (type >= (sizeof (ppc64_elf_howto_table)
+	       / sizeof (ppc64_elf_howto_table[0])))
+    {
+      (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+			     abfd, (int) type);
+      type = R_PPC64_NONE;
+    }
   cache_ptr->howto = ppc64_elf_howto_table[type];
 }
 
--- bfd/elf64-s390.c.jj	2004-11-22 15:33:31.000000000 -0500
+++ bfd/elf64-s390.c	2005-06-29 04:38:02.000000000 -0400
@@ -372,7 +372,8 @@ elf_s390_info_to_howto (abfd, cache_ptr,
      arelent *cache_ptr;
      Elf_Internal_Rela *dst;
 {
-  switch (ELF64_R_TYPE(dst->r_info))
+  unsigned int r_type = ELF64_R_TYPE(dst->r_info);
+  switch (r_type)
     {
     case R_390_GNU_VTINHERIT:
       cache_ptr->howto = &elf64_s390_vtinherit_howto;
@@ -383,8 +384,13 @@ elf_s390_info_to_howto (abfd, cache_ptr,
       break;
 
     default:
-      BFD_ASSERT (ELF64_R_TYPE(dst->r_info) < (unsigned int) R_390_max);
-      cache_ptr->howto = &elf_howto_table[ELF64_R_TYPE(dst->r_info)];
+      if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
+	{
+	  (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+				 abfd, (int) r_type);
+	  r_type = R_390_NONE;
+	}
+      cache_ptr->howto = &elf_howto_table[r_type];
     }
 }
 
--- bfd/elf32-s390.c.jj	2004-11-22 15:33:30.000000000 -0500
+++ bfd/elf32-s390.c	2005-06-29 04:38:02.000000000 -0400
@@ -350,7 +350,8 @@ elf_s390_info_to_howto (abfd, cache_ptr,
      arelent *cache_ptr;
      Elf_Internal_Rela *dst;
 {
-  switch (ELF32_R_TYPE(dst->r_info))
+  unsigned int r_type = ELF32_R_TYPE(dst->r_info);
+  switch (r_type)
     {
     case R_390_GNU_VTINHERIT:
       cache_ptr->howto = &elf32_s390_vtinherit_howto;
@@ -361,8 +362,13 @@ elf_s390_info_to_howto (abfd, cache_ptr,
       break;
 
     default:
-      BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_390_max);
-      cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)];
+      if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
+	{
+	  (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+				 abfd, (int) r_type);
+	  r_type = R_390_NONE;
+	}
+      cache_ptr->howto = &elf_howto_table[r_type];
     }
 }
 
--- bfd/elf64-x86-64.c.jj	2005-02-07 14:42:44.000000000 -0500
+++ bfd/elf64-x86-64.c	2005-06-29 04:38:02.000000000 -0400
@@ -176,16 +176,19 @@ elf64_x86_64_info_to_howto (bfd *abfd AT
   unsigned r_type, i;
 
   r_type = ELF64_R_TYPE (dst->r_info);
-  if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT)
+  if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
+      || r_type >= (unsigned int) R_X86_64_max)
     {
-      BFD_ASSERT (r_type <= (unsigned int) R_X86_64_TPOFF32);
+      if (r_type > (unsigned int) R_X86_64_TPOFF32)
+	{
+	  (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+				 abfd, (int) r_type);
+	  r_type = R_X86_64_NONE;
+	}
       i = r_type;
     }
   else
-    {
-      BFD_ASSERT (r_type < (unsigned int) R_X86_64_max);
-      i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_TPOFF32 - 1);
-    }
+    i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_TPOFF32 - 1);
   cache_ptr->howto = &x86_64_elf_howto_table[i];
   BFD_ASSERT (r_type == cache_ptr->howto->type);
 }
--- bfd/elfxx-ia64.c.jj	2005-02-18 01:14:30.000000000 -0500
+++ bfd/elfxx-ia64.c	2005-06-29 04:38:02.000000000 -0400
@@ -479,7 +479,8 @@ lookup_howto (rtype)
 	elf_code_to_howto_index[ia64_howto_table[i].type] = i;
     }
 
-  BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
+  if (rtype > R_IA64_MAX_RELOC_CODE)
+    return 0;
   i = elf_code_to_howto_index[rtype];
   if (i >= NELEMS (ia64_howto_table))
     return 0;
--- bfd/bfd-in2.h.jj	2004-12-20 14:16:48.000000000 -0500
+++ bfd/bfd-in2.h	2005-06-29 04:38:02.000000000 -0400
@@ -151,6 +151,9 @@ typedef unsigned long bfd_size_type;
 
 #endif /* not BFD64  */
 
+#define HALF_BFD_SIZE_TYPE \
+  (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
+
 #ifndef BFD_HOST_64_BIT
 /* Fall back on a 32 bit type.  The idea is to make these types always
    available for function return types, but in the case that
--- bfd/libbfd.h.jj	2004-12-20 14:16:48.000000000 -0500
+++ bfd/libbfd.h	2005-06-29 04:38:02.000000000 -0400
@@ -95,6 +95,12 @@ extern void *bfd_realloc
   (void *, bfd_size_type);
 extern void *bfd_zmalloc
   (bfd_size_type);
+extern void *bfd_malloc2
+  (bfd_size_type, bfd_size_type);
+extern void *bfd_realloc2
+  (void *, bfd_size_type, bfd_size_type);
+extern void *bfd_zmalloc2
+  (bfd_size_type, bfd_size_type);
 
 extern void _bfd_default_error_handler (const char *s, ...);
 extern bfd_error_handler_type _bfd_error_handler;
@@ -105,6 +111,10 @@ extern void *bfd_alloc
   (bfd *, bfd_size_type);
 extern void *bfd_zalloc
   (bfd *, bfd_size_type);
+extern void *bfd_alloc2
+  (bfd *, bfd_size_type, bfd_size_type);
+extern void *bfd_zalloc2
+  (bfd *, bfd_size_type, bfd_size_type);
 extern void bfd_release
   (bfd *, void *);
 
--- bfd/elf32-sparc.c.jj	2004-11-22 15:33:30.000000000 -0500
+++ bfd/elf32-sparc.c	2005-06-29 04:48:04.000000000 -0400
@@ -313,7 +313,8 @@ elf32_sparc_info_to_howto (abfd, cache_p
      arelent *cache_ptr;
      Elf_Internal_Rela *dst;
 {
-  switch (ELF32_R_TYPE(dst->r_info))
+  unsigned int r_type = ELF32_R_TYPE(dst->r_info);
+  switch (r_type)
     {
     case R_SPARC_GNU_VTINHERIT:
       cache_ptr->howto = &elf32_sparc_vtinherit_howto;
@@ -328,8 +329,13 @@ elf32_sparc_info_to_howto (abfd, cache_p
       break;
 
     default:
-      BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_SPARC_max_std);
-      cache_ptr->howto = &_bfd_sparc_elf_howto_table[ELF32_R_TYPE(dst->r_info)];
+      if (r_type >= (unsigned int) R_SPARC_max_std)
+	{
+	  (*_bfd_error_handler) (_("invalid relocation type %d"),
+				 (int) r_type);
+	  r_type = R_SPARC_NONE;
+	}
+      cache_ptr->howto = &_bfd_sparc_elf_howto_table[r_type];
     }
 }
 
--- bfd/elf64-sparc.c.jj	2004-11-22 15:33:31.000000000 -0500
+++ bfd/elf64-sparc.c	2005-06-29 04:49:42.000000000 -0400
@@ -310,8 +310,14 @@ sparc64_elf_info_to_howto (abfd, cache_p
      arelent *cache_ptr;
      Elf_Internal_Rela *dst;
 {
-  BFD_ASSERT (ELF64_R_TYPE_ID (dst->r_info) < (unsigned int) R_SPARC_max_std);
-  cache_ptr->howto = &sparc64_elf_howto_table[ELF64_R_TYPE_ID (dst->r_info)];
+  unsigned int r_type = ELF64_R_TYPE_ID (dst->r_info);
+  if (r_type >= (unsigned int) R_SPARC_max_std)
+    {
+      (*_bfd_error_handler) (_("invalid relocation type %d"),
+			     (int) r_type);
+      r_type = R_SPARC_NONE;
+    }
+  cache_ptr->howto = &sparc64_elf_howto_table[r_type];
 }
 
 struct sparc64_elf_section_data

binutils-2.15.94.0.2-robustify5.patch:
 bfd/coffcode.h         |    2 +-
 bfd/elf.c              |   23 +++++++++++++++++------
 bfd/peXXigen.c         |   12 +++++++++++-
 binutils/readelf.c     |   31 ++++++++++++++++++++++++++++++-
 include/elf/external.h |    3 +++
 5 files changed, 62 insertions(+), 9 deletions(-)

--- NEW FILE binutils-2.15.94.0.2-robustify5.patch ---
2005-06-17  Jakub Jelinek  <jakub redhat com>
bfd/
	* elf.c (bfd_section_from_shdr): Kill bogus warning.

	* elf.c (bfd_section_from_shdr): Fail if sh_entsize is bogus for
	symbol, relocation, group or versym sections.

	* coffcode.h (coff_slurp_reloc_table): Don't crash if native_relocs
	is NULL.
	* peXXigen.c (pe_print_idata): Don't crash if dll_name or start_address
	doesn't point into the section.
include/
	* elf/external.h (GRP_ENTRY_SIZE): Define.
binutils/
	* readelf.c (CHECK_ENTSIZE_VALUES, CHECK_ENTSIZE): Define.
	(process_section_headers): Use it.
	(process_relocs): Don't crash if symsec is not SHT_SYMTAB
	or SHT_DYNSYM.
	(process_version_sections): Use sizeof (Elf_External_Versym)
	instead of sh_entsize.

--- bfd/coffcode.h	9 Jun 2005 19:22:15 -0000	1.127
+++ bfd/coffcode.h	17 Jun 2005 13:39:56 -0000	1.128
@@ -4830,7 +4830,7 @@ coff_slurp_reloc_table (bfd * abfd, sec_
   amt = (bfd_size_type) asect->reloc_count * sizeof (arelent);
   reloc_cache = bfd_alloc (abfd, amt);
 
-  if (reloc_cache == NULL)
+  if (reloc_cache == NULL || native_relocs == NULL)
     return FALSE;
 
   for (idx = 0; idx < asect->reloc_count; idx++)
--- bfd/elf.c	14 Jun 2005 11:04:22 -0000	1.301
+++ bfd/elf.c	17 Jun 2005 15:48:25 -0000	1.303
@@ -1811,7 +1811,8 @@ bfd_section_from_shdr (bfd *abfd, unsign
       if (elf_onesymtab (abfd) == shindex)
 	return TRUE;
 
-      BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym);
+      if (hdr->sh_entsize != bed->s->sizeof_sym)
+	return FALSE;
       BFD_ASSERT (elf_onesymtab (abfd) == 0);
       elf_onesymtab (abfd) = shindex;
       elf_tdata (abfd)->symtab_hdr = *hdr;
@@ -1862,7 +1863,8 @@ bfd_section_from_shdr (bfd *abfd, unsign
       if (elf_dynsymtab (abfd) == shindex)
 	return TRUE;
 
-      BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym);
+      if (hdr->sh_entsize != bed->s->sizeof_sym)
+	return FALSE;
       BFD_ASSERT (elf_dynsymtab (abfd) == 0);
       elf_dynsymtab (abfd) = shindex;
       elf_tdata (abfd)->dynsymtab_hdr = *hdr;
@@ -1946,6 +1948,11 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	Elf_Internal_Shdr *hdr2;
 	unsigned int num_sec = elf_numsections (abfd);
 
+	if (hdr->sh_entsize
+	    != (bfd_size_type) (hdr->sh_type == SHT_REL
+				? bed->s->sizeof_rel : bed->s->sizeof_rela))
+	  return FALSE;
+
 	/* Check for a bogus link to avoid crashing.  */
 	if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE)
 	    || hdr->sh_link >= num_sec)
@@ -2004,10 +2011,10 @@ bfd_section_from_shdr (bfd *abfd, unsign
 	  return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
 						  shindex);
 
-        /* Prevent endless recursion on broken objects.  */
-        if (elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
-            || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
-          return FALSE;
+	/* Prevent endless recursion on broken objects.  */
+	if (elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
+	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
+	  return FALSE;
 	if (! bfd_section_from_shdr (abfd, hdr->sh_info))
 	  return FALSE;
 	target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
@@ -2047,6 +2054,8 @@ bfd_section_from_shdr (bfd *abfd, unsign
       break;
 
     case SHT_GNU_versym:
+      if (hdr->sh_entsize != sizeof (Elf_External_Versym))
+	return FALSE;
       elf_dynversym (abfd) = shindex;
       elf_tdata (abfd)->dynversym_hdr = *hdr;
       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
@@ -2065,6 +2074,8 @@ bfd_section_from_shdr (bfd *abfd, unsign
       /* We need a BFD section for objcopy and relocatable linking,
 	 and it's handy to have the signature available as the section
 	 name.  */
+      if (hdr->sh_entsize != GRP_ENTRY_SIZE)
+	return FALSE;
       name = group_signature (abfd, hdr);
       if (name == NULL)
 	return FALSE;
--- bfd/peXXigen.c	4 May 2005 15:53:37 -0000	1.30
+++ bfd/peXXigen.c	17 Jun 2005 13:39:56 -0000	1.31
@@ -1103,7 +1103,7 @@ pe_print_idata (bfd * abfd, void * vfile
       bfd_vma toc_address;
       bfd_vma start_address;
       bfd_byte *data;
-      int offset;
+      bfd_vma offset;
 
       if (!bfd_malloc_and_get_section (abfd, rel_section, &data))
 	{
@@ -1114,6 +1114,13 @@ pe_print_idata (bfd * abfd, void * vfile
 
       offset = abfd->start_address - rel_section->vma;
 
+      if (offset >= rel_section->size || offset + 8 > rel_section->size)
+        {
+          if (data != NULL)
+            free (data);
+          return FALSE;
+        }
+
       start_address = bfd_get_32 (abfd, data + offset);
       loadable_toc_address = bfd_get_32 (abfd, data + offset + 4);
       toc_address = loadable_toc_address - 32768;
@@ -1182,6 +1189,9 @@ pe_print_idata (bfd * abfd, void * vfile
       if (hint_addr == 0 && first_thunk == 0)
 	break;
 
+      if (dll_name - adj >= section->size)
+        break;
+
       dll = (char *) data + dll_name - adj;
       fprintf (file, _("\n\tDLL Name: %s\n"), dll);
 
 2005-06-08  Zack Weinberg  <zack codesourcery com>
 
 	* dis-asm.h (get_arm_regnames): Update prototype.
--- include/elf/external.h	10 May 2005 10:21:10 -0000	1.7
+++ include/elf/external.h	17 Jun 2005 13:37:23 -0000	1.8
@@ -272,5 +272,8 @@ typedef struct
   unsigned char		a_val[8];
 } Elf64_External_Auxv;
 
+/* Size of SHT_GROUP section entry.  */
+
+#define GRP_ENTRY_SIZE		4
 
 #endif /* _ELF_EXTERNAL_H */
--- binutils/readelf.c	14 Jun 2005 11:06:28 -0000	1.302
+++ binutils/readelf.c	17 Jun 2005 13:37:26 -0000	1.303
@@ -3754,6 +3754,22 @@ process_section_headers (FILE *file)
   dynamic_syminfo = NULL;
   symtab_shndx_hdr = NULL;
 
+#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
+  do									    \
+    {									    \
+      size_t expected_entsize						    \
+	= is_32bit_elf ? size32 : size64;				    \
+      if (section->sh_entsize != expected_entsize)			    \
+	error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
+	       i, (unsigned long int) section->sh_entsize,		    \
+	       (unsigned long int) expected_entsize);			    \
+      section->sh_entsize = expected_entsize;				    \
+    }									    \
+  while (0)
+#define CHECK_ENTSIZE(section, i, type) \
+  CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type),	    \
+			sizeof (Elf64_External_##type))
+
   for (i = 0, section = section_headers;
        i < elf_header.e_shnum;
        i++, section++)
@@ -3768,6 +3784,7 @@ process_section_headers (FILE *file)
 	      continue;
 	    }
 
+	  CHECK_ENTSIZE (section, i, Sym);
 	  num_dynamic_syms = section->sh_size / section->sh_entsize;
 	  dynamic_symbols = GET_ELF_SYMBOLS (file, section);
 	}
@@ -3793,6 +3810,14 @@ process_section_headers (FILE *file)
 	    }
 	  symtab_shndx_hdr = section;
 	}
+      else if (section->sh_type == SHT_SYMTAB)
+	CHECK_ENTSIZE (section, i, Sym);
+      else if (section->sh_type == SHT_GROUP)
+	CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
+      else if (section->sh_type == SHT_REL)
+	CHECK_ENTSIZE (section, i, Rel);
+      else if (section->sh_type == SHT_RELA)
+	CHECK_ENTSIZE (section, i, Rela);
       else if ((do_debugging || do_debug_info || do_debug_abbrevs
 		|| do_debug_lines || do_debug_pubnames || do_debug_aranges
 		|| do_debug_frames || do_debug_macinfo || do_debug_str
@@ -4311,6 +4336,10 @@ process_relocs (FILE *file)
 		  char *strtab = NULL;
 
 		  symsec = SECTION_HEADER (section->sh_link);
+		  if (symsec->sh_type != SHT_SYMTAB
+		      && symsec->sh_type != SHT_DYNSYM)
+                    continue;
+
 		  nsyms = symsec->sh_size / symsec->sh_entsize;
 		  symtab = GET_ELF_SYMBOLS (file, symsec);
 
@@ -6194,7 +6223,7 @@ process_version_sections (FILE *file)
 	      break;
 
 	    link_section = SECTION_HEADER (section->sh_link);
-	    total = section->sh_size / section->sh_entsize;
+	    total = section->sh_size / sizeof (Elf_External_Versym);
 
 	    if (SECTION_HEADER_INDEX (link_section->sh_link)
 		>= elf_header.e_shnum)

binutils-2.15.94.0.2-robustify6.patch:
 archive.c       |   44 ++++++++++++++++++++++++++------------------
 coff-rs6000.c   |   10 ++++++----
 coff64-rs6000.c |   10 ++++++----
 ecoff.c         |   12 +++++++-----
 libbfd-in.h     |    1 +
 libbfd.h        |    1 +
 6 files changed, 47 insertions(+), 31 deletions(-)

--- NEW FILE binutils-2.15.94.0.2-robustify6.patch ---
2005-06-21  Jakub Jelinek  <jakub redhat com>

	* libbfd-in.h (struct artdata): Add extended_names_size field.
	* libbfd.h: Rebuilt.
	* coff-rs600.c (_bfd_xcoff_archive_p): Don't clear fields in freshly
	allocated object by bfd_zalloc.
	* coff64-rs6000.c (xcoff64_archive_p): Likewise.
	* ecoff.c (_bfd_ecoff_archive_p): Likewise.
	* archive.c (_bfd_generic_mkarchive, bfd_generic_archive_p): Likewise.
	(get_extended_arelt_filename): Fail if index is bigger or equal to
	extended_names_size.
	(_bfd_generic_read_ar_hdr_mag): Don't set bfd_error_malformed_archive,
	get_extended_arelt_filename already did that.
	(_bfd_slurp_extended_name_table): Initialize extended_names_size field.
	Allocate one extra byte and clear it, in case extended names table
	is not terminated.

--- bfd/libbfd-in.h.jj	2005-06-20 12:16:18.000000000 +0200
+++ bfd/libbfd-in.h	2005-06-21 18:45:56.000000000 +0200
@@ -64,6 +64,7 @@ struct artdata {
   carsym *symdefs;		/* the symdef entries */
   symindex symdef_count;	/* how many there are */
   char *extended_names;		/* clever intel extension */
+  bfd_size_type extended_names_size; /* Size of extended names */
   /* when more compilers are standard C, this can be a time_t */
   long  armap_timestamp;	/* Timestamp value written into armap.
 				   This is used for BSD archives to check
--- bfd/libbfd.h.jj	2005-06-20 12:16:18.000000000 +0200
+++ bfd/libbfd.h	2005-06-21 18:46:32.000000000 +0200
@@ -69,6 +69,7 @@ struct artdata {
   carsym *symdefs;		/* the symdef entries */
   symindex symdef_count;	/* how many there are */
   char *extended_names;		/* clever intel extension */
+  bfd_size_type extended_names_size; /* Size of extended names */
   /* when more compilers are standard C, this can be a time_t */
   long  armap_timestamp;	/* Timestamp value written into armap.
 				   This is used for BSD archives to check
--- bfd/coff64-rs6000.c.jj	2005-06-09 10:58:49.000000000 +0200
+++ bfd/coff64-rs6000.c	2005-06-21 18:59:07.000000000 +0200
@@ -1983,10 +1983,12 @@ xcoff64_archive_p (abfd)
   if (bfd_ardata (abfd) == (struct artdata *) NULL)
     goto error_ret_restore;
 
-  bfd_ardata (abfd)->cache = NULL;
-  bfd_ardata (abfd)->archive_head = NULL;
-  bfd_ardata (abfd)->symdefs = NULL;
-  bfd_ardata (abfd)->extended_names = NULL;
+  /* Already cleared by bfd_zalloc above.
+     bfd_ardata (abfd)->cache = NULL;
+     bfd_ardata (abfd)->archive_head = NULL;
+     bfd_ardata (abfd)->symdefs = NULL;
+     bfd_ardata (abfd)->extended_names = NULL;
+     bfd_ardata (abfd)->extended_names_size = 0;  */
   bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
 							(const char **) NULL,
 							10);
--- bfd/coff-rs6000.c.jj	2005-06-09 10:58:49.000000000 +0200
+++ bfd/coff-rs6000.c	2005-06-21 18:56:11.000000000 +0200
@@ -1294,10 +1294,12 @@ _bfd_xcoff_archive_p (abfd)
   if (bfd_ardata (abfd) == (struct artdata *) NULL)
     goto error_ret_restore;
 
-  bfd_ardata (abfd)->cache = NULL;
-  bfd_ardata (abfd)->archive_head = NULL;
-  bfd_ardata (abfd)->symdefs = NULL;
-  bfd_ardata (abfd)->extended_names = NULL;
+  /* Cleared by bfd_zalloc above.
+     bfd_ardata (abfd)->cache = NULL;
+     bfd_ardata (abfd)->archive_head = NULL;
+     bfd_ardata (abfd)->symdefs = NULL;
+     bfd_ardata (abfd)->extended_names = NULL;
+     bfd_ardata (abfd)->extended_names_size = 0;  */
 
   /* Now handle the two formats.  */
   if (magic[1] != 'b')
--- bfd/ecoff.c.jj	2005-05-13 23:44:07.000000000 +0200
+++ bfd/ecoff.c	2005-06-21 18:59:49.000000000 +0200
@@ -3182,11 +3182,13 @@ _bfd_ecoff_archive_p (bfd *abfd)
     }
 
   bfd_ardata (abfd)->first_file_filepos = SARMAG;
-  bfd_ardata (abfd)->cache = NULL;
-  bfd_ardata (abfd)->archive_head = NULL;
-  bfd_ardata (abfd)->symdefs = NULL;
-  bfd_ardata (abfd)->extended_names = NULL;
-  bfd_ardata (abfd)->tdata = NULL;
+  /* Already cleared by bfd_zalloc above.
+     bfd_ardata (abfd)->cache = NULL;
+     bfd_ardata (abfd)->archive_head = NULL;
+     bfd_ardata (abfd)->symdefs = NULL;
+     bfd_ardata (abfd)->extended_names = NULL;
+     bfd_ardata (abfd)->extended_names_size = 0;
+     bfd_ardata (abfd)->tdata = NULL;  */
 
   if (! _bfd_ecoff_slurp_armap (abfd)
       || ! _bfd_ecoff_slurp_extended_name_table (abfd))
--- bfd/archive.c.jj	2005-06-17 15:22:56.000000000 +0200
+++ bfd/archive.c	2005-06-21 19:03:51.000000000 +0200
@@ -182,11 +182,13 @@ _bfd_generic_mkarchive (bfd *abfd)
   if (bfd_ardata (abfd) == NULL)
     return FALSE;
 
-  bfd_ardata (abfd)->cache = NULL;
-  bfd_ardata (abfd)->archive_head = NULL;
-  bfd_ardata (abfd)->symdefs = NULL;
-  bfd_ardata (abfd)->extended_names = NULL;
-  bfd_ardata (abfd)->tdata = NULL;
+  /* Already cleared by bfd_zalloc above.
+     bfd_ardata (abfd)->cache = NULL;
+     bfd_ardata (abfd)->archive_head = NULL;
+     bfd_ardata (abfd)->symdefs = NULL;
+     bfd_ardata (abfd)->extended_names = NULL;
+     bfd_ardata (abfd)->extended_names_size = 0;
+     bfd_ardata (abfd)->tdata = NULL;  */
 
   return TRUE;
 }
@@ -335,7 +337,7 @@ get_extended_arelt_filename (bfd *arch, 
   errno = 0;
   /* Skip first char, which is '/' in SVR4 or ' ' in some other variants.  */
   index = strtol (name + 1, NULL, 10);
-  if (errno != 0)
+  if (errno != 0 || index >= bfd_ardata (arch)->extended_names_size)
     {
       bfd_set_error (bfd_error_malformed_archive);
       return NULL;
@@ -405,10 +407,7 @@ _bfd_generic_read_ar_hdr_mag (bfd *abfd,
     {
       filename = get_extended_arelt_filename (abfd, hdr.ar_name);
       if (filename == NULL)
-	{
-	  bfd_set_error (bfd_error_malformed_archive);
-	  return NULL;
-	}
+	return NULL;
     }
   /* BSD4.4-style long filename.
      Only implemented for reading, so far!  */
@@ -629,11 +628,13 @@ bfd_generic_archive_p (bfd *abfd)
     }
 
   bfd_ardata (abfd)->first_file_filepos = SARMAG;
-  bfd_ardata (abfd)->cache = NULL;
-  bfd_ardata (abfd)->archive_head = NULL;
-  bfd_ardata (abfd)->symdefs = NULL;
-  bfd_ardata (abfd)->extended_names = NULL;
-  bfd_ardata (abfd)->tdata = NULL;
+  /* Cleared by bfd_zalloc above.
+     bfd_ardata (abfd)->cache = NULL;
+     bfd_ardata (abfd)->archive_head = NULL;
+     bfd_ardata (abfd)->symdefs = NULL;
+     bfd_ardata (abfd)->extended_names = NULL;
+     bfd_ardata (abfd)->extended_names_size = 0;
+     bfd_ardata (abfd)->tdata = NULL;  */
 
   if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))
       || !BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
@@ -1067,6 +1068,7 @@ _bfd_slurp_extended_name_table (bfd *abf
 	  strncmp (nextname, "//              ", 16) != 0)
 	{
 	  bfd_ardata (abfd)->extended_names = NULL;
+	  bfd_ardata (abfd)->extended_names_size = 0;
 	  return TRUE;
 	}
 
@@ -1075,7 +1077,11 @@ _bfd_slurp_extended_name_table (bfd *abf
 	return FALSE;
 
       amt = namedata->parsed_size;
-      bfd_ardata (abfd)->extended_names = bfd_zalloc (abfd, amt);
+      if (amt + 1 == 0)
+        goto byebye;
+
+      bfd_ardata (abfd)->extended_names_size = amt;
+      bfd_ardata (abfd)->extended_names = bfd_zalloc (abfd, amt + 1);
       if (bfd_ardata (abfd)->extended_names == NULL)
 	{
 	byebye:
@@ -1098,15 +1104,17 @@ _bfd_slurp_extended_name_table (bfd *abf
 	 trailing '/'.  DOS/NT created archive often have \ in them
 	 We'll fix all problems here..  */
       {
-	char *temp = bfd_ardata (abfd)->extended_names;
+        char *ext_names = bfd_ardata (abfd)->extended_names;
+	char *temp = ext_names;
 	char *limit = temp + namedata->parsed_size;
 	for (; temp < limit; ++temp)
 	  {
 	    if (*temp == '\012')
-	      temp[temp[-1] == '/' ? -1 : 0] = '\0';
+	      temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0';
 	    if (*temp == '\\')
 	      *temp = '/';
 	  }
+	*limit = '\0';
       }
 
       /* Pad to an even boundary if you have to.  */

binutils-2.15.94.0.2-robustify.patch:
 archive.c |    6 ++++
 elf.c     |   57 +++++++++++++++++++++++++--------------------
 elfcode.h |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 109 insertions(+), 31 deletions(-)

Index: binutils-2.15.94.0.2-robustify.patch
===================================================================
RCS file: /cvs/dist/rpms/binutils/FC-4/binutils-2.15.94.0.2-robustify.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- binutils-2.15.94.0.2-robustify.patch	25 May 2005 17:20:42 -0000	1.1
+++ binutils-2.15.94.0.2-robustify.patch	29 Jun 2005 09:26:39 -0000	1.2
@@ -1,5 +1,15 @@
-bfd/
-2005-05-25  Jakub Jelinek  <jakub redhat com>
+2005-06-14  Jakub Jelinek  <jakub redhat com>
+
+	* elf.c (bfd_elf_get_str_section): Allocate an extra byte after
+	the end of strtab and clear it.
+	(elf_read): Remove.
+
+	* elf.c (bfd_section_from_shdr): Fail if name is NULL.
+	Prevent endless recursion on broken objects.
+
+	* archive.c (do_slurp_coff_armap): Check for overflows.
+
+2005-05-26  Jakub Jelinek  <jakub redhat com>
 
 	* elfcode.h (elf_object_p): Fail if e_shoff != 0, e_shnum == 0 and
 	first shdr has sh_size == 0.  Fail if e_shnum is large to cause
@@ -20,15 +30,61 @@
 
 	* elfcode.h (elf_object_p): Add more sanity checks on elf header.
 
-binutils/
-2005-05-24  H.J. Lu  <hongjiu lu intel com>
-
-	* readelf.c (process_section_groups): Check if the section member
-	index is valid.
-
 --- bfd/elf.c.jj	2005-02-07 14:42:44.000000000 -0500
-+++ bfd/elf.c	2005-05-25 09:51:36.000000000 -0400
-@@ -443,8 +443,11 @@ group_signature (bfd *abfd, Elf_Internal
++++ bfd/elf.c	2005-06-10 19:22:09.000000000 -0400
+@@ -206,28 +206,6 @@ bfd_elf_hash (const char *namearg)
+   return h & 0xffffffff;
+ }
+ 
+-/* Read a specified number of bytes at a specified offset in an ELF
+-   file, into a newly allocated buffer, and return a pointer to the
+-   buffer.  */
+-
+-static char *
+-elf_read (bfd *abfd, file_ptr offset, bfd_size_type size)
+-{
+-  char *buf;
+-
+-  if ((buf = bfd_alloc (abfd, size)) == NULL)
+-    return NULL;
+-  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
+-    return NULL;
+-  if (bfd_bread (buf, size, abfd) != size)
+-    {
+-      if (bfd_get_error () != bfd_error_system_call)
+-	bfd_set_error (bfd_error_file_truncated);
+-      return NULL;
+-    }
+-  return buf;
+-}
+-
+ bfd_boolean
+ bfd_elf_mkobject (bfd *abfd)
+ {
+@@ -267,7 +245,21 @@ bfd_elf_get_str_section (bfd *abfd, unsi
+       /* No cached one, attempt to read, and cache what we read.  */
+       offset = i_shdrp[shindex]->sh_offset;
+       shstrtabsize = i_shdrp[shindex]->sh_size;
+-      shstrtab = elf_read (abfd, offset, shstrtabsize);
++
++      /* Allocate and clear an extra byte at the end, to prevent crashes
++	 in case the string table is not terminated.  */
++      if (shstrtabsize + 1 == 0
++	  || (shstrtab = bfd_alloc (abfd, shstrtabsize + 1)) == NULL
++	  || bfd_seek (abfd, offset, SEEK_SET) != 0)
++	shstrtab = NULL;
++      else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize)
++	{
++	  if (bfd_get_error () != bfd_error_system_call)
++	    bfd_set_error (bfd_error_file_truncated);
++	  shstrtab = NULL;
++	}
++      else
++	shstrtab[shstrtabsize] = '\0';
+       i_shdrp[shindex]->contents = shstrtab;
+     }
+   return shstrtab;
+@@ -443,8 +435,11 @@ group_signature (bfd *abfd, Elf_Internal
    Elf_External_Sym_Shndx eshndx;
    Elf_Internal_Sym isym;
  
@@ -42,7 +98,16 @@
      return NULL;
  
    /* Go read the symbol.  */
-@@ -1755,6 +1758,9 @@ bfd_section_from_shdr (bfd *abfd, unsign
+@@ -1735,6 +1730,8 @@ bfd_section_from_shdr (bfd *abfd, unsign
+   name = bfd_elf_string_from_elf_section (abfd,
+ 					  elf_elfheader (abfd)->e_shstrndx,
+ 					  hdr->sh_name);
++  if (name == NULL)
++    return FALSE;
+ 
+   switch (hdr->sh_type)
+     {
+@@ -1755,6 +1752,9 @@ bfd_section_from_shdr (bfd *abfd, unsign
      case SHT_DYNAMIC:	/* Dynamic linking information.  */
        if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
  	return FALSE;
@@ -52,6 +117,27 @@
        if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
  	{
  	  Elf_Internal_Shdr *dynsymhdr;
+@@ -1900,6 +1900,9 @@ bfd_section_from_shdr (bfd *abfd, unsign
+ 	      Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
+ 	      if (hdr2->sh_link == shindex)
+ 		{
++		  /* Prevent endless recursion on broken objects.  */
++		  if (i == shindex)
++		    return FALSE;
+ 		  if (! bfd_section_from_shdr (abfd, i))
+ 		    return FALSE;
+ 		  if (elf_onesymtab (abfd) == i)
+@@ -1975,6 +1978,10 @@ bfd_section_from_shdr (bfd *abfd, unsign
+ 	if (hdr->sh_link != elf_onesymtab (abfd) || hdr->sh_info == SHN_UNDEF)
+ 	  return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+ 
++        /* Prevent endless recursion on broken objects.  */
++        if (elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
++            || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
++          return FALSE;
+ 	if (! bfd_section_from_shdr (abfd, hdr->sh_info))
+ 	  return FALSE;
+ 	target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
 --- bfd/elfcode.h.jj	2005-02-07 14:42:44.000000000 -0500
 +++ bfd/elfcode.h	2005-05-25 13:09:21.000000000 -0400
 @@ -33,7 +33,7 @@ Foundation, Inc., 59 Temple Place - Suit
@@ -184,25 +270,21 @@
  	  if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
  	    sym->symbol.value -= sym->symbol.section->vma;
  
---- binutils/readelf.c.jj	2005-02-18 01:14:30.000000000 -0500
-+++ binutils/readelf.c	2005-05-25 13:09:39.000000000 -0400
-@@ -4067,6 +4067,19 @@ process_section_groups (FILE *file)
- 	      entry = byte_get (indices, 4);
- 	      indices += 4;
- 
-+	      if (entry >= elf_header.e_shnum)
-+		{
-+		  error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
-+			 entry, i, elf_header.e_shnum - 1);
-+		  continue;
-+		}
-+	      else if (entry >= SHN_LORESERVE && entry <= SHN_HIRESERVE)
-+		{
-+		  error (_("invalid section [%5u] in group section [%5u]\n"),
-+			 entry, i);
-+		  continue;
-+		}
+--- bfd/archive.c.jj	2005-06-10 19:02:01.000000000 +0200
++++ bfd/archive.c	2005-06-10 19:50:21.000000000 +0200
+@@ -821,9 +821,15 @@ do_slurp_coff_armap (bfd *abfd)
+   /* The coff armap must be read sequentially.  So we construct a
+      bsd-style one in core all at once, for simplicity.  */
+ 
++  if (nsymz > ~ (bfd_size_type) 0 / sizeof (carsym))
++    return FALSE;
 +
- 	      if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
- 		  != NULL)
- 		{
+   carsym_size = (nsymz * sizeof (carsym));
+   ptrsize = (4 * nsymz);
+ 
++  if (carsym_size + stringsize + 1 <= carsym_size)
++    return FALSE;
++
+   ardata->symdefs = bfd_zalloc (abfd, carsym_size + stringsize + 1);
+   if (ardata->symdefs == NULL)
+     return FALSE;


Index: binutils.spec
===================================================================
RCS file: /cvs/dist/rpms/binutils/FC-4/binutils.spec,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- binutils.spec	25 May 2005 17:20:42 -0000	1.54
+++ binutils.spec	29 Jun 2005 09:26:39 -0000	1.55
@@ -1,7 +1,7 @@
 Summary: A GNU collection of binary utilities.
 Name: binutils
 Version: 2.15.94.0.2.2
-Release: 2
+Release: 2.1
 License: GPL
 Group: Development/Tools
 URL: http://sources.redhat.com/binutils
@@ -19,6 +19,11 @@
 Patch11: binutils-2.15.94.0.2-arhdr.patch
 Patch12: binutils-2.15.94.0.2-ld-speedup.patch
 Patch13: binutils-2.15.94.0.2-robustify.patch
+Patch14: binutils-2.15.94.0.2-robustify2.patch
+Patch15: binutils-2.15.94.0.2-robustify3.patch
+Patch16: binutils-2.15.94.0.2-robustify4.patch
+Patch17: binutils-2.15.94.0.2-robustify5.patch
+Patch18: binutils-2.15.94.0.2-robustify6.patch
 
 Buildroot: %{_tmppath}/binutils-root
 BuildRequires: texinfo >= 4.0, dejagnu, gettext, flex, bison
@@ -61,6 +66,11 @@
 %patch11 -p0 -b .arhdr~
 %patch12 -p0 -b .ld-speedup~
 %patch13 -p0 -b .robustify~
+%patch14 -p0 -b .robustify2~
+%patch15 -p0 -b .robustify3~
+%patch16 -p0 -b .robustify4~
+%patch17 -p0 -b .robustify5~
+%patch18 -p0 -b .robustify6~
 # libtool sucks
 perl -pi -e 'm/LIBADD/ && s/(\.\.\/bfd\/libbfd.la)/-L\.\.\/bfd\/\.libs \1/' opcodes/Makefile.{am,in}
 # LTP sucks
@@ -169,6 +179,9 @@
 %{_infodir}/*info*
 
 %changelog
+* Wed Jun 29 2005 Jakub Jelinek <jakub redhat com> 2.15.94.0.2.2-2.1
+- further bfd, readelf and binutils robustification (CAN-2005-1704, #158680)
+
 * Wed May 25 2005 Jakub Jelinek <jakub redhat com> 2.15.94.0.2.2-2
 - bfd and readelf robustification (CAN-2005-1704, #158680)
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]