summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdw/ChangeLog4
-rw-r--r--libdw/dwarf_child.c21
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));