diff options
author | Mark Wielaard <[email protected]> | 2014-12-04 21:43:44 +0100 |
---|---|---|
committer | Mark Wielaard <[email protected]> | 2014-12-11 15:10:14 +0100 |
commit | cb73b5a015606a02f952f7eddaba15327f6191fa (patch) | |
tree | 217bc940ebda5bcf26c4be3de047a1fbd5c3359c /libdw/dwarf_getattrs.c | |
parent | edb079a596b25379828836e501d003f20afdb879 (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.c | 13 |
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; } } |