summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_getattrs.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2014-12-04 21:43:44 +0100
committerMark Wielaard <[email protected]>2014-12-11 15:10:14 +0100
commitcb73b5a015606a02f952f7eddaba15327f6191fa (patch)
tree217bc940ebda5bcf26c4be3de047a1fbd5c3359c /libdw/dwarf_getattrs.c
parentedb079a596b25379828836e501d003f20afdb879 (diff)
libdw: Add overflow checking to __libdw_form_val_len.
Pass endp as argument to __libdw_form_val_len and check we don't read beyond the end of expected data and don't return lengths that would overflow. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdw/dwarf_getattrs.c')
-rw-r--r--libdw/dwarf_getattrs.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c
index 82eb3f8f..627a8511 100644
--- a/libdw/dwarf_getattrs.c
+++ b/libdw/dwarf_getattrs.c
@@ -1,5 +1,5 @@
/* Get attributes of the DIE.
- Copyright (C) 2004, 2005, 2008, 2009 Red Hat, Inc.
+ Copyright (C) 2004, 2005, 2008, 2009, 2014 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <[email protected]>, 2004.
@@ -67,12 +67,13 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
/* Go over the list of attributes. */
Dwarf *dbg = die->cu->dbg;
+ const unsigned char *endp;
+ endp = ((const unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
+ + dbg->sectiondata[IDX_debug_abbrev]->d_size);
while (1)
{
/* Are we still in bounds? */
- if (unlikely (attrp
- >= ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
- + dbg->sectiondata[IDX_debug_abbrev]->d_size)))
+ if (unlikely (attrp >= endp))
goto invalid_dwarf;
/* Get attribute name and form. */
@@ -111,13 +112,13 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
if (attr.form != 0)
{
size_t len = __libdw_form_val_len (dbg, die->cu, attr.form,
- die_addr);
+ die_addr, endp);
if (unlikely (len == (size_t) -1l))
/* Something wrong with the file. */
return -1l;
- // XXX We need better boundary checks.
+ // __libdw_form_val_len will have done a bounds check.
die_addr += len;
}
}