summaryrefslogtreecommitdiffstats
path: root/libdw
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
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')
-rw-r--r--libdw/ChangeLog5
-rw-r--r--libdw/dwarf_siblingof.c7
2 files changed, 10 insertions, 2 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index b3093a16..9a46fac8 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,10 @@
2015-01-04 Mark Wielaard <[email protected]>
+ * dwarf_siblingof.c (dwarf_siblingof): Check sibling attribute
+ is after current DIE.
+
+2015-01-04 Mark Wielaard <[email protected]>
+
* cfi.c (enough_registers): Check reg < INT32_MAX / sizeof
(dwarf_frame_register).
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;