This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


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

Re: Invalid SHT_NOTE sections in input files


This is what I'm about to commit to fix the invalid note problem.
Differs from previous patch in that the buffer checks don't require
the name or desc area to be valid if the associated size is zero.

	* elf.c (_bfd_elf_make_section_from_shdr): Ignore return from
	elf_parse_notes.  Use bfd_malloc_and_get_section.
	(elf_parse_notes): Validate note namesz and descsz.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.457
diff -u -p -r1.457 elf.c
--- bfd/elf.c	24 Jul 2008 07:51:25 -0000	1.457
+++ bfd/elf.c	26 Jul 2008 14:49:03 -0000
@@ -935,20 +935,12 @@ _bfd_elf_make_section_from_shdr (bfd *ab
      PT_NOTEs from the core files are currently not parsed using BFD.  */
   if (hdr->sh_type == SHT_NOTE)
     {
-      char *contents;
+      bfd_byte *contents;
 
-      contents = bfd_malloc (hdr->sh_size);
-      if (!contents)
+      if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
 	return FALSE;
 
-      if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
-				     hdr->sh_size)
-	  || !elf_parse_notes (abfd, contents, hdr->sh_size, -1))
-	{
-	  free (contents);
-	  return FALSE;
-	}
-      
+      elf_parse_notes (abfd, (char *) contents, hdr->sh_size, -1);
       free (contents);
     }
 
@@ -8536,14 +8528,23 @@ elf_parse_notes (bfd *abfd, char *buf, s
       Elf_External_Note *xnp = (Elf_External_Note *) p;
       Elf_Internal_Note in;
 
+      if (offsetof (Elf_External_Note, name) > buf - p + size)
+	return FALSE;
+
       in.type = H_GET_32 (abfd, xnp->type);
 
       in.namesz = H_GET_32 (abfd, xnp->namesz);
       in.namedata = xnp->name;
+      if (in.namesz > buf - in.namedata + size)
+	return FALSE;
 
       in.descsz = H_GET_32 (abfd, xnp->descsz);
       in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
       in.descpos = offset + (in.descdata - buf);
+      if (in.descsz != 0
+	  && (in.descdata >= buf + size
+	      || in.descsz > buf - in.descdata + size))
+	return FALSE;
 
       switch (bfd_get_format (abfd))
         {

-- 
Alan Modra
Australia Development Lab, IBM


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