#define DISASS_DUMP (1 << 1)
#define DEBUG_DUMP (1 << 2)
-/* How to rpint a vma value. */
+/* How to print a vma value. */
typedef enum print_mode
{
HEX,
}
static void *
-get_data (void *var, FILE *file, long offset, size_t size, const char *reason)
+cmalloc (size_t nmemb, size_t size)
+{
+ /* Check for overflow. */
+ if (nmemb >= ~(size_t) 0 / size)
+ return NULL;
+ else
+ return malloc (nmemb * size);
+}
+
+static void *
+xcmalloc (size_t nmemb, size_t size)
+{
+ /* Check for overflow. */
+ if (nmemb >= ~(size_t) 0 / size)
+ return NULL;
+ else
+ return xmalloc (nmemb * size);
+}
+
+static void *
+xcrealloc (void *ptr, size_t nmemb, size_t size)
+{
+ /* Check for overflow. */
+ if (nmemb >= ~(size_t) 0 / size)
+ return NULL;
+ else
+ return xrealloc (ptr, nmemb * size);
+}
+
+static void *
+get_data (void *var, FILE *file, long offset, size_t size, size_t nmemb,
+ const char *reason)
{
void *mvar;
- if (size == 0)
+ if (size == 0 || nmemb == 0)
return NULL;
if (fseek (file, archive_file_offset + offset, SEEK_SET))
mvar = var;
if (mvar == NULL)
{
- mvar = malloc (size);
+ /* Check for overflow. */
+ if (nmemb < (~(size_t) 0 - 1) / size)
+ /* + 1 so that we can '\0' terminate invalid string table sections. */
+ mvar = malloc (size * nmemb + 1);
if (mvar == NULL)
{
error (_("Out of memory allocating 0x%x bytes for %s\n"),
- size, reason);
+ size * nmemb, reason);
return NULL;
}
+
+ ((char *) mvar)[size * nmemb] = '\0';
}
- if (fread (mvar, size, 1, file) != 1)
+ if (fread (mvar, size, nmemb, file) != nmemb)
{
- error (_("Unable to read in 0x%x bytes of %s\n"), size, reason);
+ error (_("Unable to read in 0x%x bytes of %s\n"), size * nmemb, reason);
if (mvar != var)
free (mvar);
return NULL;
{
Elf32_External_Rela *erelas;
- erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+ erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
if (!erelas)
return 0;
nrelas = rel_size / sizeof (Elf32_External_Rela);
- relas = malloc (nrelas * sizeof (Elf_Internal_Rela));
+ relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
if (relas == NULL)
{
+ free (erelas);
error (_("out of memory parsing relocs"));
return 0;
}
{
Elf64_External_Rela *erelas;
- erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+ erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
if (!erelas)
return 0;
nrelas = rel_size / sizeof (Elf64_External_Rela);
- relas = malloc (nrelas * sizeof (Elf_Internal_Rela));
+ relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela));
if (relas == NULL)
{
+ free (erelas);
error (_("out of memory parsing relocs"));
return 0;
}
{
Elf32_External_Rel *erels;
- erels = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+ erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
if (!erels)
return 0;
nrels = rel_size / sizeof (Elf32_External_Rel);
- rels = malloc (nrels * sizeof (Elf_Internal_Rela));
+ rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
if (rels == NULL)
{
+ free (erels);
error (_("out of memory parsing relocs"));
return 0;
}
{
Elf64_External_Rel *erels;
- erels = get_data (NULL, file, rel_offset, rel_size, _("relocs"));
+ erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs"));
if (!erels)
return 0;
nrels = rel_size / sizeof (Elf64_External_Rel);
- rels = malloc (nrels * sizeof (Elf_Internal_Rela));
+ rels = cmalloc (nrels, sizeof (Elf_Internal_Rela));
if (rels == NULL)
{
+ free (erels);
error (_("out of memory parsing relocs"));
return 0;
}
}
else if (strtab == NULL)
printf (_("<string table index: %3ld>"), psym->st_name);
- else if (psym->st_name > strtablen)
+ else if (psym->st_name >= strtablen)
printf (_("<corrupt string table index: %3ld>"), psym->st_name);
else
print_symbol (22, strtab + psym->st_name);
unsigned int i;
phdrs = get_data (NULL, file, elf_header.e_phoff,
- elf_header.e_phentsize * elf_header.e_phnum,
+ elf_header.e_phentsize, elf_header.e_phnum,
_("program headers"));
if (!phdrs)
return 0;
unsigned int i;
phdrs = get_data (NULL, file, elf_header.e_phoff,
- elf_header.e_phentsize * elf_header.e_phnum,
+ elf_header.e_phentsize, elf_header.e_phnum,
_("program headers"));
if (!phdrs)
return 0;
if (program_headers != NULL)
return 1;
- phdrs = malloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
+ phdrs = cmalloc (elf_header.e_phnum, sizeof (Elf_Internal_Phdr));
if (phdrs == NULL)
{
putc ('\n', stdout);
}
- if (do_segments && section_headers != NULL)
+ if (do_segments && section_headers != NULL && string_table != NULL)
{
printf (_("\n Section to Segment mapping:\n"));
printf (_(" Segment Sections...\n"));
- assert (string_table != NULL);
-
for (i = 0; i < elf_header.e_phnum; i++)
{
unsigned int j;
unsigned int i;
shdrs = get_data (NULL, file, elf_header.e_shoff,
- elf_header.e_shentsize * num, _("section headers"));
+ elf_header.e_shentsize, num, _("section headers"));
if (!shdrs)
return 0;
- section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
+ section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
if (section_headers == NULL)
{
unsigned int i;
shdrs = get_data (NULL, file, elf_header.e_shoff,
- elf_header.e_shentsize * num, _("section headers"));
+ elf_header.e_shentsize, num, _("section headers"));
if (!shdrs)
return 0;
- section_headers = malloc (num * sizeof (Elf_Internal_Shdr));
+ section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
if (section_headers == NULL)
{
Elf_Internal_Sym *psym;
unsigned int j;
- esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
+ esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
_("symbols"));
if (!esyms)
return NULL;
== (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
{
shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
- symtab_shndx_hdr->sh_size, _("symtab shndx"));
+ 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
if (!shndx)
{
free (esyms);
}
number = section->sh_size / section->sh_entsize;
- isyms = malloc (number * sizeof (Elf_Internal_Sym));
+ isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
if (isyms == NULL)
{
Elf_Internal_Sym *psym;
unsigned int j;
- esyms = get_data (NULL, file, section->sh_offset, section->sh_size,
+ esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
_("symbols"));
if (!esyms)
return NULL;
== (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
{
shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
- symtab_shndx_hdr->sh_size, _("symtab shndx"));
+ 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
if (!shndx)
{
free (esyms);
}
number = section->sh_size / section->sh_entsize;
- isyms = malloc (number * sizeof (Elf_Internal_Sym));
+ isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
if (isyms == NULL)
{
return 0;
/* Read in the string table, so that we have names to display. */
- section = SECTION_HEADER (elf_header.e_shstrndx);
-
- if (section->sh_size != 0)
+ if (SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum)
{
- string_table = get_data (NULL, file, section->sh_offset,
- section->sh_size, _("string table"));
+ section = SECTION_HEADER (elf_header.e_shstrndx);
- if (string_table == NULL)
- return 0;
+ if (section->sh_size != 0)
+ {
+ string_table = get_data (NULL, file, section->sh_offset,
+ 1, section->sh_size, _("string table"));
- string_table_length = section->sh_size;
+ string_table_length = string_table != NULL ? section->sh_size : 0;
+ }
}
/* Scan the sections for the dynamic symbol table
}
dynamic_strings = get_data (NULL, file, section->sh_offset,
- section->sh_size, _("dynamic strings"));
+ 1, section->sh_size, _("dynamic strings"));
dynamic_strings_length = section->sh_size;
}
else if (section->sh_type == SHT_SYMTAB_SHNDX)
Elf_Internal_Shdr *symtab_sec, *strtab_sec;
Elf_Internal_Sym *symtab;
char *strtab;
+ size_t strtab_size;
/* Don't process section groups unless needed. */
if (!do_unwind && !do_section_groups)
strtab_sec = NULL;
symtab = NULL;
strtab = NULL;
+ strtab_size = 0;
for (i = 0, section = section_headers, group = section_groups;
i < elf_header.e_shnum;
i++, section++)
Elf_Internal_Sym *sym;
/* Get the symbol table. */
- sec = SECTION_HEADER (section->sh_link);
- if (sec->sh_type != SHT_SYMTAB)
+ if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum
+ || ((sec = SECTION_HEADER (section->sh_link))->sh_type
+ != SHT_SYMTAB))
{
error (_("Bad sh_link in group section `%s'\n"), name);
continue;
}
group_name = SECTION_NAME (section_headers + sec_index);
+ strtab_sec = NULL;
+ if (strtab)
+ free (strtab);
strtab = NULL;
+ strtab_size = 0;
}
else
{
/* Get the string table. */
- sec = SECTION_HEADER (symtab_sec->sh_link);
- if (strtab_sec != sec)
+ if (SECTION_HEADER_INDEX (symtab_sec->sh_link)
+ >= elf_header.e_shnum)
+ {
+ strtab_sec = NULL;
+ if (strtab)
+ free (strtab);
+ strtab = NULL;
+ strtab_size = 0;
+ }
+ else if (strtab_sec
+ != (sec = SECTION_HEADER (symtab_sec->sh_link)))
{
strtab_sec = sec;
if (strtab)
free (strtab);
strtab = get_data (NULL, file, strtab_sec->sh_offset,
- strtab_sec->sh_size,
+ 1, strtab_sec->sh_size,
_("string table"));
+ strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
}
- group_name = strtab + sym->st_name;
+ group_name = sym->st_name < strtab_size
+ ? strtab + sym->st_name : "<corrupt>";
}
start = get_data (NULL, file, section->sh_offset,
- section->sh_size, _("section data"));
+ 1, section->sh_size, _("section data"));
indices = start;
size = (section->sh_size / section->sh_entsize) - 1;
entry = byte_get (indices, 4);
indices += 4;
- if (entry >= elf_header.e_shnum)
+ if (SECTION_HEADER_INDEX (entry) >= elf_header.e_shnum)
{
error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
entry, i, elf_header.e_shnum - 1);
if (do_section_groups)
{
sec = SECTION_HEADER (entry);
- printf (" [%5u] %s\n",
- entry, SECTION_NAME (sec));
+ printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
}
g = xmalloc (sizeof (struct group_list));
is_rela = section->sh_type == SHT_RELA;
- if (section->sh_link)
+ if (section->sh_link
+ && SECTION_HEADER_INDEX (section->sh_link)
+ < elf_header.e_shnum)
{
Elf_Internal_Shdr *symsec;
Elf_Internal_Sym *symtab;
unsigned long nsyms;
- unsigned long strtablen;
+ unsigned long strtablen = 0;
char *strtab = NULL;
symsec = SECTION_HEADER (section->sh_link);
if (symtab == NULL)
continue;
- strsec = SECTION_HEADER (symsec->sh_link);
+ if (SECTION_HEADER_INDEX (symsec->sh_link)
+ < elf_header.e_shnum)
+ {
+ strsec = SECTION_HEADER (symsec->sh_link);
- strtab = get_data (NULL, file, strsec->sh_offset,
- strsec->sh_size, _("string table"));
- strtablen = strtab == NULL ? 0 : strsec->sh_size;
+ strtab = get_data (NULL, file, strsec->sh_offset,
+ 1, strsec->sh_size,
+ _("string table"));
+ strtablen = strtab == NULL ? 0 : strsec->sh_size;
+ }
dump_relocations (file, rel_offset, rel_size,
symtab, nsyms, strtab, strtablen, is_rela);
/* Second, build the unwind table from the contents of the unwind section: */
size = sec->sh_size;
- table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
+ table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
if (!table)
return 0;
- aux->table = xmalloc (size / (3 * eh_addr_size) * sizeof (aux->table[0]));
+ aux->table = xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
tep = aux->table;
for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
{
++relsec)
{
if (relsec->sh_type != SHT_RELA
+ || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
|| SECTION_HEADER (relsec->sh_info) != sec)
continue;
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
{
- if (sec->sh_type == SHT_SYMTAB)
+ if (sec->sh_type == SHT_SYMTAB
+ && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
{
aux.nsyms = sec->sh_size / sec->sh_entsize;
aux.symtab = GET_ELF_SYMBOLS (file, sec);
strsec = SECTION_HEADER (sec->sh_link);
- aux.strtab_size = strsec->sh_size;
aux.strtab = get_data (NULL, file, strsec->sh_offset,
- aux.strtab_size, _("string table"));
+ 1, strsec->sh_size, _("string table"));
+ aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
}
else if (sec->sh_type == SHT_IA_64_UNWIND)
unwcount++;
{
aux.info_size = sec->sh_size;
aux.info_addr = sec->sh_addr;
- aux.info = get_data (NULL, file, sec->sh_offset, aux.info_size,
+ aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
_("unwind info"));
printf (_("\nUnwind section "));
/* Second, build the unwind table from the contents of the unwind
section. */
size = sec->sh_size;
- table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
+ table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
if (!table)
return 0;
unw_ent_size = 2 * eh_addr_size + 8;
- tep = aux->table = xmalloc (size / unw_ent_size * sizeof (aux->table[0]));
+ tep = aux->table = xcmalloc (size / unw_ent_size, sizeof (aux->table[0]));
for (tp = table; tp < table + size; tp += (2 * eh_addr_size + 8), ++tep)
{
++relsec)
{
if (relsec->sh_type != SHT_RELA
+ || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
|| SECTION_HEADER (relsec->sh_info) != sec)
continue;
memset (& aux, 0, sizeof (aux));
- assert (string_table != NULL);
+ if (string_table == NULL)
+ return 1;
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
{
- if (sec->sh_type == SHT_SYMTAB)
+ if (sec->sh_type == SHT_SYMTAB
+ && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
{
aux.nsyms = sec->sh_size / sec->sh_entsize;
aux.symtab = GET_ELF_SYMBOLS (file, sec);
strsec = SECTION_HEADER (sec->sh_link);
- aux.strtab_size = strsec->sh_size;
aux.strtab = get_data (NULL, file, strsec->sh_offset,
- aux.strtab_size, _("string table"));
+ 1, strsec->sh_size, _("string table"));
+ aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
}
else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
unwsec = sec;
Elf32_External_Dyn *edyn, *ext;
Elf_Internal_Dyn *entry;
- edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
+ edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
_("dynamic section"));
if (!edyn)
return 0;
break;
}
- dynamic_section = malloc (dynamic_nent * sizeof (*entry));
+ dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
if (dynamic_section == NULL)
{
error (_("Out of memory\n"));
Elf64_External_Dyn *edyn, *ext;
Elf_Internal_Dyn *entry;
- edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
+ edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
_("dynamic section"));
if (!edyn)
return 0;
break;
}
- dynamic_section = malloc (dynamic_nent * sizeof (*entry));
+ dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
if (dynamic_section == NULL)
{
error (_("Out of memory\n"));
continue;
}
- dynamic_strings = get_data (NULL, file, offset, str_tab_len,
+ dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
_("dynamic string table"));
dynamic_strings_length = str_tab_len;
break;
Elf_Internal_Syminfo *syminfo;
/* There is a syminfo section. Read the data. */
- extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, syminsz,
- _("symbol information"));
+ extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
+ syminsz, _("symbol information"));
if (!extsyminfo)
return 0;
printf_vma (section->sh_addr);
printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
(unsigned long) section->sh_offset, section->sh_link,
- SECTION_NAME (SECTION_HEADER (section->sh_link)));
+ SECTION_HEADER_INDEX (section->sh_link)
+ < elf_header.e_shnum
+ ? SECTION_NAME (SECTION_HEADER (section->sh_link))
+ : "<corrupt>");
- edefs = get_data (NULL, file, section->sh_offset, section->sh_size,
+ edefs = get_data (NULL, file, section->sh_offset, 1,
+ section->sh_size,
_("version definition section"));
if (!edefs)
break;
printf_vma (section->sh_addr);
printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
(unsigned long) section->sh_offset, section->sh_link,
- SECTION_NAME (SECTION_HEADER (section->sh_link)));
+ SECTION_HEADER_INDEX (section->sh_link)
+ < elf_header.e_shnum
+ ? SECTION_NAME (SECTION_HEADER (section->sh_link))
+ : "<corrupt>");
- eneed = get_data (NULL, file, section->sh_offset, section->sh_size,
+ eneed = get_data (NULL, file, section->sh_offset, 1,
+ section->sh_size,
_("version need section"));
if (!eneed)
break;
Elf_Internal_Shdr *string_sec;
long off;
+ if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
+ break;
+
link_section = SECTION_HEADER (section->sh_link);
total = section->sh_size / section->sh_entsize;
+ if (SECTION_HEADER_INDEX (link_section->sh_link)
+ >= elf_header.e_shnum)
+ break;
+
found = 1;
symbols = GET_ELF_SYMBOLS (file, link_section);
string_sec = SECTION_HEADER (link_section->sh_link);
- strtab = get_data (NULL, file, string_sec->sh_offset,
+ strtab = get_data (NULL, file, string_sec->sh_offset, 1,
string_sec->sh_size, _("version string table"));
if (!strtab)
break;
off = offset_from_vma (file,
version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
total * sizeof (short));
- edata = get_data (NULL, file, off, total * sizeof (short),
+ edata = get_data (NULL, file, off, total, sizeof (short),
_("version symbol data"));
if (!edata)
{
break;
}
- data = malloc (total * sizeof (short));
+ data = cmalloc (total, sizeof (short));
for (cnt = total; cnt --;)
data[cnt] = byte_get (edata + cnt * sizeof (short),
check_def = 1;
check_need = 1;
- if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
- != SHT_NOBITS)
+ if (SECTION_HEADER_INDEX (symbols[cnt + j].st_shndx)
+ >= elf_header.e_shnum
+ || SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
+ != SHT_NOBITS)
{
if (symbols[cnt + j].st_shndx == SHN_UNDEF)
check_def = 0;
Elf_External_Vernaux evna;
unsigned long a_off;
- get_data (&evn, file, offset, sizeof (evn),
+ get_data (&evn, file, offset, sizeof (evn), 1,
_("version need"));
ivn.vn_aux = BYTE_GET (evn.vn_aux);
do
{
get_data (&evna, file, a_off, sizeof (evna),
- _("version need aux (2)"));
+ 1, _("version need aux (2)"));
ivna.vna_next = BYTE_GET (evna.vna_next);
ivna.vna_other = BYTE_GET (evna.vna_other);
do
{
- get_data (&evd, file, offset, sizeof (evd),
+ get_data (&evd, file, offset, sizeof (evd), 1,
_("version def"));
ivd.vd_next = BYTE_GET (evd.vd_next);
get_data (&evda, file,
offset - ivd.vd_next + ivd.vd_aux,
- sizeof (evda), _("version def aux"));
+ sizeof (evda), 1,
+ _("version def aux"));
ivda.vda_name = BYTE_GET (evda.vda_name);
unsigned char *e_data;
bfd_vma *i_data;
- e_data = malloc (number * ent_size);
+ e_data = cmalloc (number, ent_size);
if (e_data == NULL)
{
return NULL;
}
- i_data = malloc (number * sizeof (*i_data));
+ i_data = cmalloc (number, sizeof (*i_data));
if (i_data == NULL)
{
i++, section++)
{
unsigned int si;
- char *strtab;
+ char *strtab = NULL;
+ unsigned long int strtab_size = 0;
Elf_Internal_Sym *symtab;
Elf_Internal_Sym *psym;
continue;
if (section->sh_link == elf_header.e_shstrndx)
- strtab = string_table;
- else
+ {
+ strtab = string_table;
+ strtab_size = string_table_length;
+ }
+ else if (SECTION_HEADER_INDEX (section->sh_link) < elf_header.e_shnum)
{
Elf_Internal_Shdr *string_sec;
string_sec = SECTION_HEADER (section->sh_link);
strtab = get_data (NULL, file, string_sec->sh_offset,
- string_sec->sh_size, _("string table"));
+ 1, string_sec->sh_size, _("string table"));
+ strtab_size = strtab != NULL ? string_sec->sh_size : 0;
}
for (si = 0, psym = symtab;
printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
printf (" %4s ", get_symbol_index_type (psym->st_shndx));
- print_symbol (25, strtab + psym->st_name);
+ print_symbol (25, psym->st_name < strtab_size
+ ? strtab + psym->st_name : "<corrupt>");
if (section->sh_type == SHT_DYNSYM &&
version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
sizeof data + si * sizeof (vers_data));
get_data (&data, file, offset + si * sizeof (vers_data),
- sizeof (data), _("version data"));
+ sizeof (data), 1, _("version data"));
vers_data = byte_get (data, 2);
- is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type
- == SHT_NOBITS);
+ is_nobits = (SECTION_HEADER_INDEX (psym->st_shndx)
+ < elf_header.e_shnum
+ && SECTION_HEADER (psym->st_shndx)->sh_type
+ == SHT_NOBITS);
check_def = (psym->st_shndx != SHN_UNDEF);
{
unsigned long vna_off;
- get_data (&evn, file, offset, sizeof (evn),
+ get_data (&evn, file, offset, sizeof (evn), 1,
_("version need"));
ivn.vn_aux = BYTE_GET (evn.vn_aux);
Elf_External_Vernaux evna;
get_data (&evna, file, vna_off,
- sizeof (evna),
+ sizeof (evna), 1,
_("version need aux (3)"));
ivna.vna_other = BYTE_GET (evna.vna_other);
if (ivna.vna_other == vers_data)
{
printf ("@%s (%d)",
- strtab + ivna.vna_name, ivna.vna_other);
+ ivna.vna_name < strtab_size
+ ? strtab + ivna.vna_name : "<corrupt>",
+ ivna.vna_other);
check_def = 0;
}
else if (! is_nobits)
Elf_External_Verdef evd;
get_data (&evd, file, offset, sizeof (evd),
- _("version def"));
+ 1, _("version def"));
ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
ivd.vd_aux = BYTE_GET (evd.vd_aux);
offset += ivd.vd_aux;
get_data (&evda, file, offset, sizeof (evda),
- _("version def aux"));
+ 1, _("version def aux"));
ivda.vda_name = BYTE_GET (evda.vda_name);
if (psym->st_name != ivda.vda_name)
printf ((vers_data & 0x8000)
? "@%s" : "@@%s",
- strtab + ivda.vda_name);
+ ivda.vda_name < strtab_size
+ ? strtab + ivda.vda_name : "<corrupt>");
}
}
}
addr = section->sh_addr;
- start = get_data (NULL, file, section->sh_offset, bytes, _("section data"));
+ start = get_data (NULL, file, section->sh_offset, 1, bytes,
+ _("section data"));
if (!start)
return 0;
debug_str_size = sec->sh_size;
- debug_str_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+ debug_str_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
_("debug_str section data"));
}
debug_loc_size = sec->sh_size;
- debug_loc_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+ debug_loc_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
_("debug_loc section data"));
}
debug_range_size = sec->sh_size;
- debug_range_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+ debug_range_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
_("debug_range section data"));
}
Elf_Internal_Sym *sym;
if (relsec->sh_type != SHT_RELA
+ || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
|| SECTION_HEADER (relsec->sh_info) != section
- || relsec->sh_size == 0)
+ || relsec->sh_size == 0
+ || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
continue;
if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
{
max += 1024;
debug_info_p->loc_offsets
- = xrealloc (debug_info_p->loc_offsets,
- max * sizeof (*debug_info_p->loc_offsets));
+ = xcrealloc (debug_info_p->loc_offsets,
+ max, sizeof (*debug_info_p->loc_offsets));
debug_info_p->have_frame_base
- = xrealloc (debug_info_p->have_frame_base,
- max * sizeof (*debug_info_p->have_frame_base));
+ = xcrealloc (debug_info_p->have_frame_base,
+ max, sizeof (*debug_info_p->have_frame_base));
debug_info_p->max_loc_offsets = max;
}
debug_info_p->loc_offsets [num] = uvalue;
{
max += 1024;
debug_info_p->range_lists
- = xrealloc (debug_info_p->range_lists,
- max * sizeof (*debug_info_p->range_lists));
+ = xcrealloc (debug_info_p->range_lists,
+ max, sizeof (*debug_info_p->range_lists));
debug_info_p->max_range_lists = max;
}
debug_info_p->range_lists [num] = uvalue;
}
/* Then allocate an array to hold the information. */
- debug_information = malloc (num_units *
- sizeof (* debug_information));
+ debug_information = cmalloc (num_units,
+ sizeof (* debug_information));
if (debug_information == NULL)
{
error (_("Not enough memory for a debug info array of %u entries"),
return 0;
}
- begin = get_data (NULL, file, sec->sh_offset, sec->sh_size,
+ begin = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
_("debug_abbrev section data"));
if (!begin)
return 0;
if (section == NULL)
return 0;
- start = get_data (NULL, file, section->sh_offset, section->sh_size,
+ start = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
_("extracting information from .debug_info section"));
if (start == NULL)
return 0;
}
start = next;
+ if (offset >= bytes)
+ {
+ warn (_("Offset 0x%lx is bigger than .debug_loc section size.\n"),
+ offset);
+ continue;
+ }
+
while (1)
{
+ if (start + 2 * pointer_size > section_end)
+ {
+ warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+ offset);
+ break;
+ }
+
begin = byte_get (start, pointer_size);
start += pointer_size;
end = byte_get (start, pointer_size);
if (begin == -1UL && end != -1UL)
{
base_address = end;
- printf (" %8.8lx %8.8lx %8.8lx (base address)\n",
+ printf (_(" %8.8lx %8.8lx %8.8lx (base address)\n"),
offset, begin, end);
continue;
}
+ if (start + 2 > section_end)
+ {
+ warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+ offset);
+ break;
+ }
+
length = byte_get (start, 2);
start += 2;
+ if (start + length > section_end)
+ {
+ warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+ offset);
+ break;
+ }
+
printf (" %8.8lx %8.8lx %8.8lx (",
offset, begin + base_address, end + base_address);
need_frame_base = decode_location_expression (start,
return;
fc->ncols = reg + 1;
- fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int));
- fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int));
+ fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int));
+ fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
while (prev < fc->ncols)
{
else
{
fc->ncols = cie->ncols;
- fc->col_type = xmalloc (fc->ncols * sizeof (short int));
- fc->col_offset = xmalloc (fc->ncols * sizeof (int));
+ fc->col_type = xcmalloc (fc->ncols, sizeof (short int));
+ fc->col_offset = xcmalloc (fc->ncols, sizeof (int));
memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
fc->augmentation = cie->augmentation;
printf (" DW_CFA_remember_state\n");
rs = xmalloc (sizeof (Frame_Chunk));
rs->ncols = fc->ncols;
- rs->col_type = xmalloc (rs->ncols * sizeof (short int));
- rs->col_offset = xmalloc (rs->ncols * sizeof (int));
+ rs->col_type = xcmalloc (rs->ncols, sizeof (short int));
+ rs->col_offset = xcmalloc (rs->ncols, sizeof (int));
memcpy (rs->col_type, fc->col_type, rs->ncols);
memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
rs->next = remembered_state;
{
unsigned char *start;
- start = get_data (NULL, file, section->sh_offset, length,
+ start = get_data (NULL, file, section->sh_offset, 1, length,
_("debug section data"));
if (start == NULL)
{
size_t cnt;
elib = get_data (NULL, file, liblist_offset,
- liblistno * sizeof (Elf32_External_Lib),
+ liblistno, sizeof (Elf32_External_Lib),
_("liblist"));
if (elib)
{
while (sect->sh_type != SHT_MIPS_OPTIONS)
++sect;
- eopt = get_data (NULL, file, options_offset, sect->sh_size,
+ eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
_("options"));
if (eopt)
{
- iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt));
+ iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt));
if (iopt == NULL)
{
error (_("Out of memory"));
return 0;
}
- iconf = malloc (conflictsno * sizeof (*iconf));
+ iconf = cmalloc (conflictsno, sizeof (*iconf));
if (iconf == NULL)
{
error (_("Out of memory"));
Elf32_External_Conflict *econf32;
econf32 = get_data (NULL, file, conflicts_offset,
- conflictsno * sizeof (*econf32), _("conflict"));
+ conflictsno, sizeof (*econf32), _("conflict"));
if (!econf32)
return 0;
Elf64_External_Conflict *econf64;
econf64 = get_data (NULL, file, conflicts_offset,
- conflictsno * sizeof (*econf64), _("conflict"));
+ conflictsno, sizeof (*econf64), _("conflict"));
if (!econf64)
return 0;
Elf_Internal_Shdr *section, *string_sec;
Elf32_External_Lib *elib;
char *strtab;
+ size_t strtab_size;
size_t cnt;
unsigned i;
switch (section->sh_type)
{
case SHT_GNU_LIBLIST:
- elib = get_data (NULL, file, section->sh_offset, section->sh_size,
+ if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
+ break;
+
+ elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
_("liblist"));
if (elib == NULL)
break;
string_sec = SECTION_HEADER (section->sh_link);
- strtab = get_data (NULL, file, string_sec->sh_offset,
+ strtab = get_data (NULL, file, string_sec->sh_offset, 1,
string_sec->sh_size, _("liblist string table"));
+ strtab_size = string_sec->sh_size;
if (strtab == NULL
|| section->sh_entsize != sizeof (Elf32_External_Lib))
printf ("%3lu: ", (unsigned long) cnt);
if (do_wide)
- printf ("%-20s", strtab + liblist.l_name);
+ printf ("%-20s", liblist.l_name < strtab_size
+ ? strtab + liblist.l_name : "<corrupt>");
else
- printf ("%-20.20s", strtab + liblist.l_name);
+ printf ("%-20.20s", liblist.l_name < strtab_size
+ ? strtab + liblist.l_name : "<corrupt>");
printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
liblist.l_version, liblist.l_flags);
}
if (length <= 0)
return 0;
- pnotes = get_data (NULL, file, offset, length, _("notes"));
+ pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
if (!pnotes)
return 0;