summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_siblingof.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2015-01-05 00:03:03 +0100
committerMark Wielaard <[email protected]>2015-01-15 14:21:43 +0100
commit43e924ee0bb01576cb30a7069ad9183e55b1093b (patch)
tree3c7a8a855b32eacd96c1df7d158d733fcda4fe36 /libdw/dwarf_siblingof.c
parenta1ea2423c0245d4a9f84523bcb5cb7cc96a27ec8 (diff)
libdw: Check DW_AT_sibling attribute offset is after current DIE.
The sibling attribute should point after this DIE in the CU. Otherwise various algorithms might loop or go into infinite recursion walking the DIE tree. Found by afl-fuzz. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdw/dwarf_siblingof.c')
-rw-r--r--libdw/dwarf_siblingof.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/libdw/dwarf_siblingof.c b/libdw/dwarf_siblingof.c
index f8241b37..e598ae41 100644
--- a/libdw/dwarf_siblingof.c
+++ b/libdw/dwarf_siblingof.c
@@ -1,5 +1,5 @@
/* Return sibling of given DIE.
- Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+ Copyright (C) 2003-2010, 2014, 2015 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <[email protected]>, 2003.
@@ -79,8 +79,11 @@ dwarf_siblingof (die, result)
/* Something went wrong. */
return -1;
+ /* The sibling attribute should point after this DIE in the CU.
+ But not after the end of the CU. */
size_t size = sibattr.cu->endp - sibattr.cu->startp;
- if (unlikely (offset >= size))
+ size_t die_off = this_die.addr - this_die.cu->startp;
+ if (unlikely (offset >= size || offset <= die_off))
{
__libdw_seterrno (DWARF_E_INVALID_DWARF);
return -1;