diff options
| -rw-r--r-- | libdw/ChangeLog | 4 | ||||
| -rw-r--r-- | libdw/dwarf_child.c | 21 |
2 files changed, 19 insertions, 6 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index b0ba7e00..e31fabf9 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,7 @@ +2011-03-09 Petr Machata <[email protected]> + + * libdw/dwarf_child.c (dwarf_child): Check for section overrun. + 2011-02-23 Roland McGrath <[email protected]> * libdwP.h (struct Dwarf) [USE_ZLIB]: New member sectiondata_gzip_mask. diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c index 0080cf9d..1ec3704e 100644 --- a/libdw/dwarf_child.c +++ b/libdw/dwarf_child.c @@ -1,5 +1,5 @@ /* Return child of current DIE. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc. + Copyright (C) 2003-2011 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper <[email protected]>, 2003. @@ -175,18 +175,27 @@ dwarf_child (die, result) if (addr == NULL) return -1; + /* RESULT can be the same as DIE. So preserve what we need. */ + struct Dwarf_CU *cu = die->cu; + /* It's kosher (just suboptimal) to have a null entry first thing (7.5.3). So if this starts with ULEB128 of 0 (even with silly encoding of 0), it is a kosher null entry and we do not really have any children. */ const unsigned char *code = addr; - while (unlikely (*code == 0x80)) - ++code; + const unsigned char *endp = (cu->dbg->sectiondata[IDX_debug_info]->d_buf + + cu->dbg->sectiondata[IDX_debug_info]->d_size); + while (1) + { + if (unlikely (code >= endp)) /* Truncated section. */ + return 1; + if (unlikely (*code == 0x80)) + ++code; + else + break; + } if (unlikely (*code == '\0')) return 1; - /* RESULT can be the same as DIE. So preserve what we need. */ - struct Dwarf_CU *cu = die->cu; - /* Clear the entire DIE structure. This signals we have not yet determined any of the information. */ memset (result, '\0', sizeof (Dwarf_Die)); |
