PR binutils/15191

* readelf.c (offsetof): Define.
	(CHECK_ENTSIZE_VALUES): Remove extraneous indefinite article.
	(process_corefile_note_segment): Allow notes without name or
	desc.  Combine out-of-range checks.  Disallow "negative"
	notesz or descsz.
This commit is contained in:
Alan Modra 2013-02-27 12:40:15 +00:00
parent 727f703102
commit 15b42fb01d
2 changed files with 74 additions and 72 deletions

View File

@ -1,3 +1,12 @@
2013-02-27 Alan Modra <amodra@gmail.com>
PR binutils/15191
* readelf.c (offsetof): Define.
(CHECK_ENTSIZE_VALUES): Remove extraneous indefinite article.
(process_corefile_note_segment): Allow notes without name or
desc. Combine out-of-range checks. Disallow "negative"
notesz or descsz.
2013-02-26 Nick Clifton <nickc@redhat.com>
PR binutils/15191
@ -78,14 +87,14 @@
2013-01-25 Cary Coutant <ccoutant@google.com>
* dwarf.c (display_loc_list): Update offset for each line
printed.
(print_addr_index): New function.
(display_loc_list_dwo): Update offset for each line printed.
Fix problems displaying loclists in .dwo files. Add support
for type 4 entries.
(display_debug_loc): Remove custom header for .dwo files.
(display_debug_addr): Adjust formatting.
* dwarf.c (display_loc_list): Update offset for each line
printed.
(print_addr_index): New function.
(display_loc_list_dwo): Update offset for each line printed.
Fix problems displaying loclists in .dwo files. Add support
for type 4 entries.
(display_debug_loc): Remove custom header for .dwo files.
(display_debug_addr): Adjust formatting.
2013-01-25 Marco Atzeri <marco.atzeri@gmail.com>

View File

@ -160,6 +160,10 @@
#include "safe-ctype.h"
#include "filenames.h"
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
#endif
char * program_name = "readelf";
static long archive_file_offset;
static unsigned long archive_file_size;
@ -4754,7 +4758,7 @@ process_section_headers (FILE * file)
bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
if (section->sh_entsize != expected_entsize) \
{ \
error (_("Section %d has invalid an sh_entsize of %" BFD_VMA_FMT "x\n"), \
error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
i, section->sh_entsize); \
error (_("(Using the expected size of %d for the rest of this dump)\n"), \
(int) expected_entsize); \
@ -13340,13 +13344,12 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
Elf_External_Note * pnotes;
Elf_External_Note * external;
int res = 1;
bfd_signed_vma data_remaining;
if (length <= 0)
return 0;
pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
_("notes"));
_("notes"));
if (pnotes == NULL)
return 0;
@ -13356,79 +13359,69 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
(unsigned long) offset, (unsigned long) length);
printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
data_remaining = length;
while (external < (Elf_External_Note *) ((char *) pnotes + length))
while ((char *) external < (char *) pnotes + length)
{
Elf_External_Note * next;
Elf_Internal_Note inote;
size_t min_notesz;
char *next;
char * temp = NULL;
size_t data_remaining = ((char *) pnotes + length) - (char *) external;
if (!is_ia64_vms ())
{
/* PR binutils/15191
Make sure that there is enough data to read. */
if (data_remaining < sizeof * next)
{
warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
(int) data_remaining);
break;
}
inote.type = BYTE_GET (external->type);
inote.namesz = BYTE_GET (external->namesz);
inote.namedata = external->name;
inote.descsz = BYTE_GET (external->descsz);
inote.descdata = inote.namedata + align_power (inote.namesz, 2);
inote.descpos = offset + (inote.descdata - (char *) pnotes);
next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
}
else
{
Elf64_External_VMS_Note *vms_external;
/* PR binutils/15191
Make sure that there is enough data to read. */
if (data_remaining < sizeof * vms_external)
{
warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
(int) data_remaining);
break;
}
vms_external = (Elf64_External_VMS_Note *) external;
inote.type = BYTE_GET (vms_external->type);
inote.namesz = BYTE_GET (vms_external->namesz);
inote.namedata = vms_external->name;
inote.descsz = BYTE_GET (vms_external->descsz);
inote.descdata = inote.namedata + align_power (inote.namesz, 3);
inote.descpos = offset + (inote.descdata - (char *) pnotes);
next = (Elf_External_Note *)
(inote.descdata + align_power (inote.descsz, 3));
}
data_remaining -= ((char *) next - (char *) external);
if (data_remaining < 0)
{
warn (_("note with invalid namesz &/or descsz found at offset 0x%lx\n"),
/* PR binutils/15191
Make sure that there is enough data to read. */
min_notesz = offsetof (Elf_External_Note, name);
if (data_remaining < min_notesz)
{
warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
(int) data_remaining);
break;
}
inote.type = BYTE_GET (external->type);
inote.namesz = BYTE_GET (external->namesz);
inote.namedata = external->name;
inote.descsz = BYTE_GET (external->descsz);
inote.descdata = inote.namedata + align_power (inote.namesz, 2);
inote.descpos = offset + (inote.descdata - (char *) pnotes);
next = inote.descdata + align_power (inote.descsz, 2);
}
else
{
Elf64_External_VMS_Note *vms_external;
/* PR binutils/15191
Make sure that there is enough data to read. */
min_notesz = offsetof (Elf64_External_VMS_Note, name);
if (data_remaining < min_notesz)
{
warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
(int) data_remaining);
break;
}
vms_external = (Elf64_External_VMS_Note *) external;
inote.type = BYTE_GET (vms_external->type);
inote.namesz = BYTE_GET (vms_external->namesz);
inote.namedata = vms_external->name;
inote.descsz = BYTE_GET (vms_external->descsz);
inote.descdata = inote.namedata + align_power (inote.namesz, 3);
inote.descpos = offset + (inote.descdata - (char *) pnotes);
next = inote.descdata + align_power (inote.descsz, 3);
}
if (inote.descdata < (char *) external + min_notesz
|| next < (char *) external + min_notesz
|| data_remaining < (size_t)(next - (char *) external))
{
warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
(unsigned long) ((char *) external - (char *) pnotes));
warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
inote.type, inote.namesz, inote.descsz);
break;
}
external = next;
/* Prevent out-of-bounds indexing. */
if (inote.namedata + inote.namesz > (char *) pnotes + length
|| inote.namedata + inote.namesz < inote.namedata)
{
warn (_("note with invalid namesz found at offset 0x%lx\n"),
(unsigned long) ((char *) external - (char *) pnotes));
warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
inote.type, inote.namesz, inote.descsz);
break;
}
external = (Elf_External_Note *) next;
/* Verify that name is null terminated. It appears that at least
one version of Linux (RedHat 6.0) generates corefiles that don't