This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Invalid SHT_NOTE sections in input files
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Sun, 27 Jul 2008 13:09:57 +0930
- Subject: Re: Invalid SHT_NOTE sections in input files
- References: <20080624213253.GA22565@caradoc.them.org> <20080708111309.GA15838@bubble.grove.modra.org>
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