mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-19 17:18:24 +08:00
display_debug_names
* dwarf.c (display_debug_names): Complain when header length is too small. Avoid pointer UB. Sanity check augmentation string, CU table, TU table and foreign TU table sizes.
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
2021-05-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* dwarf.c (display_debug_names): Complain when header length is
|
||||||
|
too small. Avoid pointer UB. Sanity check augmentation string,
|
||||||
|
CU table, TU table and foreign TU table sizes.
|
||||||
|
|
||||||
2021-05-15 Alan Modra <amodra@gmail.com>
|
2021-05-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* dwarf.c (display_debug_frames): Delete initial_length_size.
|
* dwarf.c (display_debug_frames): Delete initial_length_size.
|
||||||
|
@ -9571,12 +9571,12 @@ display_debug_names (struct dwarf_section *section, void *file)
|
|||||||
unsigned int offset_size;
|
unsigned int offset_size;
|
||||||
uint16_t dwarf_version, padding;
|
uint16_t dwarf_version, padding;
|
||||||
uint32_t comp_unit_count, local_type_unit_count, foreign_type_unit_count;
|
uint32_t comp_unit_count, local_type_unit_count, foreign_type_unit_count;
|
||||||
uint32_t bucket_count, name_count, abbrev_table_size;
|
uint64_t bucket_count, name_count, abbrev_table_size;
|
||||||
uint32_t augmentation_string_size;
|
uint32_t augmentation_string_size;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned long sec_off;
|
|
||||||
bool augmentation_printable;
|
bool augmentation_printable;
|
||||||
const char *augmentation_string;
|
const char *augmentation_string;
|
||||||
|
size_t total;
|
||||||
|
|
||||||
unit_start = hdrptr;
|
unit_start = hdrptr;
|
||||||
|
|
||||||
@ -9591,18 +9591,18 @@ display_debug_names (struct dwarf_section *section, void *file)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
offset_size = 4;
|
offset_size = 4;
|
||||||
unit_end = hdrptr + unit_length;
|
|
||||||
|
|
||||||
sec_off = hdrptr - section->start;
|
if (unit_length > (size_t) (section_end - hdrptr)
|
||||||
if (sec_off + unit_length < sec_off
|
|| unit_length < 2 + 2 + 4 * 7)
|
||||||
|| sec_off + unit_length > section->size)
|
|
||||||
{
|
{
|
||||||
|
too_short:
|
||||||
warn (_("Debug info is corrupted, %s header at %#lx has length %s\n"),
|
warn (_("Debug info is corrupted, %s header at %#lx has length %s\n"),
|
||||||
section->name,
|
section->name,
|
||||||
(unsigned long) (unit_start - section->start),
|
(unsigned long) (unit_start - section->start),
|
||||||
dwarf_vmatoa ("x", unit_length));
|
dwarf_vmatoa ("x", unit_length));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
unit_end = hdrptr + unit_length;
|
||||||
|
|
||||||
/* Get and check the version number. */
|
/* Get and check the version number. */
|
||||||
SAFE_BYTE_GET_AND_INC (dwarf_version, hdrptr, 2, unit_end);
|
SAFE_BYTE_GET_AND_INC (dwarf_version, hdrptr, 2, unit_end);
|
||||||
@ -9640,6 +9640,8 @@ display_debug_names (struct dwarf_section *section, void *file)
|
|||||||
augmentation_string_size);
|
augmentation_string_size);
|
||||||
augmentation_string_size += (-augmentation_string_size) & 3;
|
augmentation_string_size += (-augmentation_string_size) & 3;
|
||||||
}
|
}
|
||||||
|
if (augmentation_string_size > (size_t) (unit_end - hdrptr))
|
||||||
|
goto too_short;
|
||||||
|
|
||||||
printf (_("Augmentation string:"));
|
printf (_("Augmentation string:"));
|
||||||
|
|
||||||
@ -9669,6 +9671,9 @@ display_debug_names (struct dwarf_section *section, void *file)
|
|||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
|
||||||
printf (_("CU table:\n"));
|
printf (_("CU table:\n"));
|
||||||
|
if (_mul_overflow (comp_unit_count, offset_size, &total)
|
||||||
|
|| total > (size_t) (unit_end - hdrptr))
|
||||||
|
goto too_short;
|
||||||
for (i = 0; i < comp_unit_count; i++)
|
for (i = 0; i < comp_unit_count; i++)
|
||||||
{
|
{
|
||||||
uint64_t cu_offset;
|
uint64_t cu_offset;
|
||||||
@ -9679,6 +9684,9 @@ display_debug_names (struct dwarf_section *section, void *file)
|
|||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
|
||||||
printf (_("TU table:\n"));
|
printf (_("TU table:\n"));
|
||||||
|
if (_mul_overflow (local_type_unit_count, offset_size, &total)
|
||||||
|
|| total > (size_t) (unit_end - hdrptr))
|
||||||
|
goto too_short;
|
||||||
for (i = 0; i < local_type_unit_count; i++)
|
for (i = 0; i < local_type_unit_count; i++)
|
||||||
{
|
{
|
||||||
uint64_t tu_offset;
|
uint64_t tu_offset;
|
||||||
@ -9689,6 +9697,9 @@ display_debug_names (struct dwarf_section *section, void *file)
|
|||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
|
||||||
printf (_("Foreign TU table:\n"));
|
printf (_("Foreign TU table:\n"));
|
||||||
|
if (_mul_overflow (foreign_type_unit_count, 8, &total)
|
||||||
|
|| total > (size_t) (unit_end - hdrptr))
|
||||||
|
goto too_short;
|
||||||
for (i = 0; i < foreign_type_unit_count; i++)
|
for (i = 0; i < foreign_type_unit_count; i++)
|
||||||
{
|
{
|
||||||
uint64_t signature;
|
uint64_t signature;
|
||||||
@ -9700,6 +9711,18 @@ display_debug_names (struct dwarf_section *section, void *file)
|
|||||||
}
|
}
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
|
||||||
|
uint64_t xtra = (bucket_count * sizeof (uint32_t)
|
||||||
|
+ name_count * (sizeof (uint32_t) + 2 * offset_size)
|
||||||
|
+ abbrev_table_size);
|
||||||
|
if (xtra > (size_t) (unit_end - hdrptr))
|
||||||
|
{
|
||||||
|
warn (_("Entry pool offset (0x%lx) exceeds unit size 0x%lx "
|
||||||
|
"for unit 0x%lx in the debug_names\n"),
|
||||||
|
(long) xtra,
|
||||||
|
(long) (unit_end - unit_start),
|
||||||
|
(long) (unit_start - section->start));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
const uint32_t *const hash_table_buckets = (uint32_t *) hdrptr;
|
const uint32_t *const hash_table_buckets = (uint32_t *) hdrptr;
|
||||||
hdrptr += bucket_count * sizeof (uint32_t);
|
hdrptr += bucket_count * sizeof (uint32_t);
|
||||||
const uint32_t *const hash_table_hashes = (uint32_t *) hdrptr;
|
const uint32_t *const hash_table_hashes = (uint32_t *) hdrptr;
|
||||||
@ -9712,15 +9735,6 @@ display_debug_names (struct dwarf_section *section, void *file)
|
|||||||
hdrptr += abbrev_table_size;
|
hdrptr += abbrev_table_size;
|
||||||
const unsigned char *const abbrev_table_end = hdrptr;
|
const unsigned char *const abbrev_table_end = hdrptr;
|
||||||
unsigned char *const entry_pool = hdrptr;
|
unsigned char *const entry_pool = hdrptr;
|
||||||
if (hdrptr > unit_end)
|
|
||||||
{
|
|
||||||
warn (_("Entry pool offset (0x%lx) exceeds unit size 0x%lx "
|
|
||||||
"for unit 0x%lx in the debug_names\n"),
|
|
||||||
(long) (hdrptr - section->start),
|
|
||||||
(long) (unit_end - section->start),
|
|
||||||
(long) (unit_start - section->start));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t buckets_filled = 0;
|
size_t buckets_filled = 0;
|
||||||
size_t bucketi;
|
size_t bucketi;
|
||||||
|
Reference in New Issue
Block a user