mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 02:24:17 +08:00
Work around problem in DWARF decoding library which can result in attempts to read arbitrary bytes as if they were an LEB128 encoded value.
* dwarf.c (skip_attr_bytes): Accept DWARF versions higher than 4 when processing the DW_FORM_ref_addr form. Skip bytes in DW_FORM_block and DW_FORM_exprloc forms. Handle DW_FORM_indirect. (get_type_signedness): Allow a limited amount of recursion. Do not attempt to decode types that use the DW_FORM_ref_addr form. (read_and_display_attr_value): Do not attempt to decode types that use the DW_FORM_ref_addr form.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2020-10-21 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* dwarf.c (skip_attr_bytes): Accept DWARF versions higher than 4
|
||||||
|
when processing the DW_FORM_ref_addr form.
|
||||||
|
Skip bytes in DW_FORM_block and DW_FORM_exprloc forms.
|
||||||
|
Handle DW_FORM_indirect.
|
||||||
|
(get_type_signedness): Allow a limited amount of recursion.
|
||||||
|
Do not attempt to decode types that use the DW_FORM_ref_addr form.
|
||||||
|
(read_and_display_attr_value): Do not attempt to decode types
|
||||||
|
that use the DW_FORM_ref_addr form.
|
||||||
|
|
||||||
2020-10-20 Alan Modra <amodra@gmail.com>
|
2020-10-20 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* readelf.c: Delete whitespace at end of line throughout.
|
* readelf.c: Delete whitespace at end of line throughout.
|
||||||
|
@ -1868,7 +1868,7 @@ skip_attr_bytes (unsigned long form,
|
|||||||
case DW_FORM_ref_addr:
|
case DW_FORM_ref_addr:
|
||||||
if (dwarf_version == 2)
|
if (dwarf_version == 2)
|
||||||
SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
|
SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
|
||||||
else if (dwarf_version == 3 || dwarf_version == 4)
|
else if (dwarf_version > 2)
|
||||||
SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
|
SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1920,6 +1920,7 @@ skip_attr_bytes (unsigned long form,
|
|||||||
|
|
||||||
case DW_FORM_ref8:
|
case DW_FORM_ref8:
|
||||||
case DW_FORM_data8:
|
case DW_FORM_data8:
|
||||||
|
case DW_FORM_ref_sig8:
|
||||||
data += 8;
|
data += 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1934,6 +1935,7 @@ skip_attr_bytes (unsigned long form,
|
|||||||
case DW_FORM_block:
|
case DW_FORM_block:
|
||||||
case DW_FORM_exprloc:
|
case DW_FORM_exprloc:
|
||||||
READ_ULEB (uvalue, data, end);
|
READ_ULEB (uvalue, data, end);
|
||||||
|
data += uvalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_block1:
|
case DW_FORM_block1:
|
||||||
@ -1951,12 +1953,12 @@ skip_attr_bytes (unsigned long form,
|
|||||||
data += 4 + uvalue;
|
data += 4 + uvalue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_ref_sig8:
|
|
||||||
data += 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DW_FORM_indirect:
|
case DW_FORM_indirect:
|
||||||
/* FIXME: Handle this form. */
|
READ_ULEB (form, data, end);
|
||||||
|
if (form == DW_FORM_implicit_const)
|
||||||
|
SKIP_ULEB (data, end);
|
||||||
|
return skip_attr_bytes (form, data, end, pointer_size, offset_size, dwarf_version, value_return);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1978,7 +1980,7 @@ get_type_signedness (unsigned char * start,
|
|||||||
dwarf_vma offset_size,
|
dwarf_vma offset_size,
|
||||||
int dwarf_version,
|
int dwarf_version,
|
||||||
bfd_boolean * is_signed,
|
bfd_boolean * is_signed,
|
||||||
bfd_boolean is_nested)
|
unsigned int nesting)
|
||||||
{
|
{
|
||||||
unsigned long abbrev_number;
|
unsigned long abbrev_number;
|
||||||
abbrev_entry * entry;
|
abbrev_entry * entry;
|
||||||
@ -1997,6 +1999,14 @@ get_type_signedness (unsigned char * start,
|
|||||||
/* FIXME: Issue a warning ? */
|
/* FIXME: Issue a warning ? */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#define MAX_NESTING 20
|
||||||
|
if (nesting > MAX_NESTING)
|
||||||
|
{
|
||||||
|
/* FIXME: Warn - or is this expected ?
|
||||||
|
NB/ We need to avoid infinite recursion. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (attr = entry->first_attr;
|
for (attr = entry->first_attr;
|
||||||
attr != NULL && attr->attribute;
|
attr != NULL && attr->attribute;
|
||||||
attr = attr->next)
|
attr = attr->next)
|
||||||
@ -2019,16 +2029,12 @@ get_type_signedness (unsigned char * start,
|
|||||||
#endif
|
#endif
|
||||||
case DW_AT_type:
|
case DW_AT_type:
|
||||||
/* Recurse. */
|
/* Recurse. */
|
||||||
if (is_nested)
|
|
||||||
{
|
|
||||||
/* FIXME: Warn - or is this expected ?
|
|
||||||
NB/ We need to avoid infinite recursion. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (uvalue >= (size_t) (end - start))
|
if (uvalue >= (size_t) (end - start))
|
||||||
return;
|
return;
|
||||||
|
/* We cannot correctly process DW_FORM_ref_addr at the moment. */
|
||||||
|
if (attr->form != DW_FORM_ref_addr)
|
||||||
get_type_signedness (start, start + uvalue, end, pointer_size,
|
get_type_signedness (start, start + uvalue, end, pointer_size,
|
||||||
offset_size, dwarf_version, is_signed, TRUE);
|
offset_size, dwarf_version, is_signed, nesting + 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_AT_encoding:
|
case DW_AT_encoding:
|
||||||
@ -2206,7 +2212,6 @@ read_and_display_attr_value (unsigned long attribute,
|
|||||||
SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
|
SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
|
||||||
else
|
else
|
||||||
error (_("Internal error: DW_FORM_ref_addr is not supported in DWARF version 1.\n"));
|
error (_("Internal error: DW_FORM_ref_addr is not supported in DWARF version 1.\n"));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_addr:
|
case DW_FORM_addr:
|
||||||
@ -2663,8 +2668,10 @@ read_and_display_attr_value (unsigned long attribute,
|
|||||||
{
|
{
|
||||||
bfd_boolean is_signed = FALSE;
|
bfd_boolean is_signed = FALSE;
|
||||||
|
|
||||||
|
/* We cannot correctly process DW_FORM_ref_addr at the moment. */
|
||||||
|
if (form != DW_FORM_ref_addr)
|
||||||
get_type_signedness (start, start + uvalue, end, pointer_size,
|
get_type_signedness (start, start + uvalue, end, pointer_size,
|
||||||
offset_size, dwarf_version, & is_signed, FALSE);
|
offset_size, dwarf_version, & is_signed, 0);
|
||||||
level_type_signed[level] = is_signed;
|
level_type_signed[level] = is_signed;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user