aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorWill Newton <will.newton@linaro.org>2013-11-01 14:14:50 -0700
committerWill Newton <will.newton@linaro.org>2013-11-06 15:15:12 +0000
commitb9502d3fd7848cd4d843be8bdc28633a3d24438d (patch)
tree8160e3a77056ebca0faeb0aa6893b826d6da8441 /gdb/dwarf2read.c
parent452a569eff947a21369d43cc7632c320e5b8a085 (diff)
downloadgdb-b9502d3fd7848cd4d843be8bdc28633a3d24438d.zip
gdb-b9502d3fd7848cd4d843be8bdc28633a3d24438d.tar.gz
gdb-b9502d3fd7848cd4d843be8bdc28633a3d24438d.tar.bz2
gdb/dwarf2read.c: Sanity check DW_AT_sibling values.
When reading objects with corrupt debug information it is possible that the sibling chain can form a loop, which leads to an infinite loop and memory exhaustion. Avoid this situation by disregarding and DW_AT_sibling values that point to a lower address than the current entry. gdb/ChangeLog: 2013-11-06 Will Newton <will.newton@linaro.org> PR gdb/12866 * dwarf2read.c (skip_one_die): Sanity check DW_AT_sibling values. (read_partial_die): Likewise.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 3974d0b..bc8e8ca 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -7016,7 +7016,16 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
complaint (&symfile_complaints,
_("ignoring absolute DW_AT_sibling"));
else
- return buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
+ {
+ unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off;
+ const gdb_byte *sibling_ptr = buffer + off;
+
+ if (sibling_ptr < info_ptr)
+ complaint (&symfile_complaints,
+ _("DW_AT_sibling points backwards"));
+ else
+ return sibling_ptr;
+ }
}
/* If it isn't DW_AT_sibling, skip this attribute. */
@@ -15134,7 +15143,16 @@ read_partial_die (const struct die_reader_specs *reader,
complaint (&symfile_complaints,
_("ignoring absolute DW_AT_sibling"));
else
- part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
+ {
+ unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off;
+ const gdb_byte *sibling_ptr = buffer + off;
+
+ if (sibling_ptr < info_ptr)
+ complaint (&symfile_complaints,
+ _("DW_AT_sibling points backwards"));
+ else
+ part_die->sibling = sibling_ptr;
+ }
break;
case DW_AT_byte_size:
part_die->has_byte_size = 1;