This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Further bfd robustification


Hi!

E.g. if e_shstrndx is valid, but its Shdr has sh_offset outside of
file boundaries, bfd_section_from_shdr crashes when it attempts to
create a section with NULL name.
If there are sh_info/sh_link loops, e.g. in:
  [ 1] .text             PROGBITS        0000000000000000 000040 000060 00  AX  0   0 16
  [ 2] .rela.text        RELA            0000000000000000 000648 000060 18     12   2  8
...
  [12] .symtab           SYMTAB          0000000000000000 000510 000120 18     13   9  8
(note section 2's sh_info being 2), bfd_section_from_shdr might
end up doing infinite recursion and crash.

Plus there is a possible heap overflow in do_slurp_coff_armap.

Note that I don't think this is the only one in bfd (in the last
patch for readelf I have tried to catch up as many as possible in
readelf), do you think we can add new bfd_*alloc functions that
will have 2 bfd_size_type arguments rather than one and allocate
size * nmemb provided it doesn't overflow, otherwise fail?

2005-06-11  Jakub Jelinek  <jakub@redhat.com>

	* 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.

--- bfd/elf.c.jj	2005-06-09 10:58:50.000000000 +0200
+++ bfd/elf.c	2005-06-11 01:06:21.000000000 +0200
@@ -1752,6 +1752,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)
     {
@@ -1922,6 +1924,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)
@@ -1999,6 +2004,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;
 	if (! bfd_section_from_shdr (abfd, hdr->sh_info))
 	  return FALSE;
 	target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
--- 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;
+
   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;

	Jakub


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