More fixes for assertion failures and out-of-bounds reads by readelf.

PR binutils/17531
	* (ia64_process_unwind): Replace assertion with an error message.
	Add range checking for group section indicies.
	(hppa_process_unwind): Replace assertion with an error message.
	(process_syminfo): Likewise.
	(decode_arm_unwind_bytecode): Add range checking.
	(dump_section_as_strings): Add more string range checking.
	(display_tag_value): Likewise.
	(display_arm_attribute): Likewise.
	(display_gnu_attribute): Likewise.
	(display_tic6x_attribute): Likewise.
	(display_msp430x_attribute): Likewise.
This commit is contained in:
Nick Clifton
2014-11-10 16:32:32 +00:00
parent 5e186ece2f
commit 4082ef8464
2 changed files with 145 additions and 53 deletions

View File

@ -1,3 +1,18 @@
2014-11-10 Nick Clifton <nickc@redhat.com>
PR binutils/17531
* (ia64_process_unwind): Replace assertion with an error message.
Add range checking for group section indicies.
(hppa_process_unwind): Replace assertion with an error message.
(process_syminfo): Likewise.
(decode_arm_unwind_bytecode): Add range checking.
(dump_section_as_strings): Add more string range checking.
(display_tag_value): Likewise.
(display_arm_attribute): Likewise.
(display_gnu_attribute): Likewise.
(display_tic6x_attribute): Likewise.
(display_msp430x_attribute): Likewise.
2014-11-10 Nick Clifton <nickc@redhat.com>
PR binutils/17552

View File

@ -6467,7 +6467,11 @@ ia64_process_unwind (FILE * file)
aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
strsec = section_headers + sec->sh_link;
assert (aux.strtab == NULL);
if (aux.strtab != NULL)
{
error (_("Multiple auxillary string tables encountered\n"));
free (aux.strtab);
}
aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
1, strsec->sh_size,
_("string table"));
@ -6485,13 +6489,16 @@ ia64_process_unwind (FILE * file)
char * suffix;
size_t len, len2;
for (i = unwstart, sec = section_headers + unwstart;
for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
i < elf_header.e_shnum; ++i, ++sec)
if (sec->sh_type == SHT_IA_64_UNWIND)
{
unwsec = sec;
break;
}
/* We have already counted the number of SHT_IA64_UNWIND
sections so the loop above should never fail. */
assert (unwsec != NULL);
unwstart = i + 1;
len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
@ -6499,7 +6506,14 @@ ia64_process_unwind (FILE * file)
if ((unwsec->sh_flags & SHF_GROUP) != 0)
{
/* We need to find which section group it is in. */
struct group_list * g = section_headers_groups [i]->root;
struct group_list * g;
if (section_headers_groups == NULL
|| section_headers_groups [i] == NULL)
i = elf_header.e_shnum;
else
{
g = section_headers_groups [i]->root;
for (; g != NULL; g = g->next)
{
@ -6512,6 +6526,7 @@ ia64_process_unwind (FILE * file)
if (g == NULL)
i = elf_header.e_shnum;
}
}
else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
{
/* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
@ -6878,7 +6893,11 @@ hppa_process_unwind (FILE * file)
aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
strsec = section_headers + sec->sh_link;
assert (aux.strtab == NULL);
if (aux.strtab != NULL)
{
error (_("Multiple auxillary string tables encountered\n"));
free (aux.strtab);
}
aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
1, strsec->sh_size,
_("string table"));
@ -7359,12 +7378,16 @@ decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
if ((buf[i] & 0x80) == 0)
break;
}
assert (i < sizeof (buf));
if (i == sizeof (buf))
printf (_("corrupt change to vsp"));
else
{
offset = read_uleb128 (buf, &len, buf + i + 1);
assert (len == i + 1);
offset = offset * 4 + 0x204;
printf ("vsp = vsp + %ld", offset);
}
}
else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
{
unsigned int first, last;
@ -7880,7 +7903,7 @@ arm_process_unwind (FILE *file)
/* PR binutils/17531 file: 011-12666-0.004. */
if (aux.strtab != NULL)
{
warn (_("Multiple string tables found in file.\n"));
error (_("Multiple string tables found in file.\n"));
free (aux.strtab);
}
aux.strtab = get_data (NULL, file, strsec->sh_offset,
@ -10469,8 +10492,9 @@ process_syminfo (FILE * file ATTRIBUTE_UNUSED)
unsigned short int flags = dynamic_syminfo[i].si_flags;
printf ("%4d: ", i);
assert (i < num_dynamic_syms);
if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
if (i >= num_dynamic_syms)
printf (_("<corrupt index>"));
else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
else
printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
@ -11321,9 +11345,17 @@ dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
#else
printf (" [%6Ix] ", (size_t) (data - start));
#endif
if (maxlen > 0)
{
print_symbol ((int) maxlen, data);
putchar ('\n');
data += strnlen (data, maxlen);
}
else
{
printf (_("<corrupt>\n"));
data = end;
}
some_strings_shown = TRUE;
}
}
@ -11764,7 +11796,7 @@ display_tag_value (int tag,
if (p >= end)
{
warn (_("corrupt tag\n"));
warn (_("<corrupt tag>\n"));
}
else if (tag & 1)
{
@ -11772,10 +11804,18 @@ display_tag_value (int tag,
size_t maxlen = (end - p) - 1;
putchar ('"');
if (maxlen > 0)
{
print_symbol ((int) maxlen, (const char *) p);
printf ("\"\n");
p += strnlen ((char *) p, maxlen) + 1;
}
else
{
printf (_("<corrupt string tag>"));
p = (unsigned char *) end;
}
printf ("\"\n");
}
else
{
unsigned int len;
@ -11785,6 +11825,7 @@ display_tag_value (int tag,
printf ("%ld (0x%lx)\n", val, val);
}
assert (p <= end);
return p;
}
@ -11993,16 +12034,23 @@ display_arm_attribute (unsigned char * p,
case 32: /* Tag_compatibility. */
{
size_t maxlen;
val = read_uleb128 (p, &len, end);
p += len;
maxlen = (end - p) - 1;
printf (_("flag = %d, vendor = "), val);
if (p < end - 1)
{
size_t maxlen = (end - p) - 1;
print_symbol ((int) maxlen, (const char *) p);
putchar ('\n');
p += strnlen ((char *) p, maxlen) + 1;
}
else
{
printf (_("<corrupt>"));
p = (unsigned char *) end;
}
putchar ('\n');
}
break;
case 64: /* Tag_nodefaults. */
@ -12080,13 +12128,21 @@ display_gnu_attribute (unsigned char * p,
warn (_("corrupt vendor attribute\n"));
}
else
{
if (p < end - 1)
{
size_t maxlen = (end - p) - 1;
print_symbol ((int) maxlen, (const char *) p);
putchar ('\n');
p += strnlen ((char *) p, maxlen) + 1;
}
else
{
printf (_("<corrupt>"));
p = (unsigned char *) end;
}
putchar ('\n');
}
return p;
}
@ -12583,29 +12639,42 @@ display_tic6x_attribute (unsigned char * p,
case Tag_ABI_compatibility:
{
size_t maxlen;
val = read_uleb128 (p, &len, end);
p += len;
printf (" Tag_ABI_compatibility: ");
maxlen = (end - p) - 1;
printf (_("flag = %d, vendor = "), val);
if (p < end - 1)
{
size_t maxlen = (end - p) - 1;
print_symbol ((int) maxlen, (const char *) p);
putchar ('\n');
p += strnlen ((char *) p, maxlen) + 1;
}
else
{
printf (_("<corrupt>"));
p = (unsigned char *) end;
}
putchar ('\n');
return p;
}
case Tag_ABI_conformance:
{
size_t maxlen;
printf (" Tag_ABI_conformance: \"");
if (p < end - 1)
{
size_t maxlen = (end - p) - 1;
printf (" Tag_ABI_conformance: ");
maxlen = (end - p) - 1;
putchar ('"');
print_symbol ((int) maxlen, (const char *) p);
printf ("\"\n");
p += strnlen ((char *) p, maxlen) + 1;
}
else
{
printf (_("<corrupt>"));
p = (unsigned char *) end;
}
printf ("\"\n");
return p;
}
}
@ -12716,14 +12785,21 @@ display_msp430x_attribute (unsigned char * p,
if (tag & 1)
{
size_t maxlen;
maxlen = (end - p) - 1;
putchar ('"');
if (p < end - 1)
{
size_t maxlen = (end - p) - 1;
print_symbol ((int) maxlen, (const char *) p);
printf ("\"\n");
p += strnlen ((char *) p, maxlen) + 1;
}
else
{
printf (_("<corrupt>"));
p = (unsigned char *) end;
}
printf ("\"\n");
}
else
{
val = read_uleb128 (p, &len, end);
@ -12733,6 +12809,7 @@ display_msp430x_attribute (unsigned char * p,
break;
}
assert (p <= end);
return p;
}