diff options
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf-attrs.c | 9 | ||||
-rw-r--r-- | binutils/ChangeLog | 6 | ||||
-rw-r--r-- | binutils/readelf.c | 25 |
4 files changed, 34 insertions, 12 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9e60287..253e061 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2014-03-06 Nick Clifton <nickc@redhat.com> + + PR 16664 + * elf-attrs.c (_bfd_elf_parse_attributes): Add checks for corrupt + attribute section names. + 2014-03-05 Alan Modra <amodra@gmail.com> Update copyright years. diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c index d2ef769..cd0cbca 100644 --- a/bfd/elf-attrs.c +++ b/bfd/elf-attrs.c @@ -449,7 +449,7 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr) len = hdr->sh_size - 1; while (len > 0) { - int namelen; + unsigned namelen; bfd_vma section_len; int vendor; @@ -458,8 +458,11 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr) if (section_len > len) section_len = len; len -= section_len; - namelen = strlen ((char *) p) + 1; - section_len -= namelen + 4; + section_len -= 4; + namelen = strnlen ((char *) p, section_len) + 1; + if (namelen == 0 || namelen >= section_len) + break; + section_len -= namelen; if (std_sec && strcmp ((char *) p, std_sec) == 0) vendor = OBJ_ATTR_PROC; else if (strcmp ((char *) p, "gnu") == 0) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 3db21f1..13ae6aa 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2014-03-06 Nick Clifton <nickc@redhat.com> + + PR binutils/16664 + * readelf.c (process_attributes): Add checks for corrupt + attribute section names. + 2014-03-05 Alan Modra <amodra@gmail.com> Update copyright years. diff --git a/binutils/readelf.c b/binutils/readelf.c index 12c2ea3..27682b2 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -12420,7 +12420,7 @@ process_attributes (FILE * file, while (len > 0) { - int namelen; + unsigned int namelen; bfd_boolean public_section; bfd_boolean gnu_section; @@ -12429,12 +12429,21 @@ process_attributes (FILE * file, if (section_len > len) { - printf (_("ERROR: Bad section length (%d > %d)\n"), - (int) section_len, (int) len); + error (_("Length of attribute (%u) greater than length of section (%u)\n"), + (unsigned) section_len, (unsigned) len); section_len = len; } len -= section_len; + section_len -= 4; + + namelen = strnlen ((char *) p, section_len) + 1; + if (namelen == 0 || namelen >= section_len) + { + error (_("Corrupt attribute section name\n")); + break; + } + printf (_("Attribute Section: %s\n"), p); if (public_name && streq ((char *) p, public_name)) @@ -12447,10 +12456,8 @@ process_attributes (FILE * file, else gnu_section = FALSE; - namelen = strlen ((char *) p) + 1; p += namelen; - section_len -= namelen + 4; - + section_len -= namelen; while (section_len > 0) { int tag = *(p++); @@ -12460,8 +12467,8 @@ process_attributes (FILE * file, size = byte_get (p, 4); if (size > section_len) { - printf (_("ERROR: Bad subsection length (%d > %d)\n"), - (int) size, (int) section_len); + error (_("Bad subsection length (%u > %u)\n"), + (unsigned) size, (unsigned) section_len); size = section_len; } @@ -12520,7 +12527,7 @@ process_attributes (FILE * file, } } else - printf (_("Unknown format '%c'\n"), *p); + printf (_("Unknown format '%c' (%d)\n"), *p, *p); free (contents); } |