2016-08-08 Nick Clifton <nickc@redhat.com>
+ PR binutils/20440
+ * dwarf.c (display_debug_lines_decoded): Add checks for running
+ off the end of the section when populating the directory table and
+ file table.
+ (frame_display_row): Set max_regs equal to ncols.
+ (load_specific_debug_section): If the section is compressed, but
+ it is not big enough to hold a compression header then warn and
+ return 0.
+
PR binutils/20439
* dwarf.c (display_debug_lines_decoded): Check directory and file
indicies before using them to access directory and file tables.
/* Traverse the Directory table just to count entries. */
data = standard_opcodes + linfo.li_opcode_base - 1;
+ /* PR 20440 */
+ if (data >= end)
+ {
+ warn (_("opcode base of %d extends beyond end of section\n"),
+ linfo.li_opcode_base);
+ return 0;
+ }
+
if (*data != 0)
{
unsigned char *ptr_directory_table = data;
- while (*data != 0)
+ while (data < end && *data != 0)
{
data += strnlen ((char *) data, end - data) + 1;
n_directories++;
}
+ /* PR 20440 */
+ if (data >= end)
+ {
+ warn (_("directory table ends unexpectedly\n"));
+ n_directories = 0;
+ break;
+ }
+
/* Go through the directory table again to save the directories. */
directory_table = (unsigned char **)
xmalloc (n_directories * sizeof (unsigned char *));
data++;
/* Traverse the File Name table just to count the entries. */
- if (*data != 0)
+ if (data < end && *data != 0)
{
unsigned char *ptr_file_name_table = data;
- while (*data != 0)
+ while (data < end && *data != 0)
{
unsigned int bytes_read;
n_files++;
}
+ if (data >= end)
+ {
+ warn (_("file table ends unexpectedly\n"));
+ n_files = 0;
+ break;
+ }
+
/* Go through the file table again to save the strings. */
file_table = (File_Entry *) xmalloc (n_files * sizeof (File_Entry));
unsigned int r;
char tmp[100];
- if (*max_regs < fc->ncols)
+ if (*max_regs != fc->ncols)
*max_regs = fc->ncols;
if (*need_col_headers)
if (is_32bit_elf)
{
Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
+
chdr->ch_type = BYTE_GET (echdr->ch_type);
chdr->ch_size = BYTE_GET (echdr->ch_size);
chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
else
{
Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
+
chdr->ch_type = BYTE_GET (echdr->ch_type);
chdr->ch_size = BYTE_GET (echdr->ch_size);
chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
/* Minimum section size is 12 bytes for 32-bit compression
header + 12 bytes for compressed data header. */
unsigned char buf[24];
+
assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
if (get_data (&buf, (FILE *) file, section->sh_offset, 1,
sizeof (buf), _("compression header")))
{
Elf_Internal_Chdr chdr;
- get_compression_header (&chdr, buf);
+
+ (void) get_compression_header (&chdr, buf);
+
if (chdr.ch_type == ELFCOMPRESS_ZLIB)
printf (" ZLIB, ");
else
if ((sec->sh_flags & SHF_COMPRESSED) != 0)
{
Elf_Internal_Chdr chdr;
- unsigned int compression_header_size
- = get_compression_header (&chdr, start);
+ unsigned int compression_header_size;
+
+ if (size < sizeof chdr)
+ {
+ warn (_("compressed section %s is too small to contain a compression header"),
+ section->name);
+ return 0;
+ }
+
+ compression_header_size = get_compression_header (&chdr, start);
+
if (chdr.ch_type != ELFCOMPRESS_ZLIB)
{
warn (_("section '%s' has unsupported compress type: %d\n"),