]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Check DW_AT_sibling attribute offset is after current DIE.
authorMark Wielaard <mjw@redhat.com>
Sun, 4 Jan 2015 23:03:03 +0000 (00:03 +0100)
committerMark Wielaard <mjw@redhat.com>
Thu, 15 Jan 2015 13:21:43 +0000 (14:21 +0100)
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 <mjw@redhat.com>
libdw/ChangeLog
libdw/dwarf_siblingof.c

index b3093a16c9e9850fa548d018d578079df1b344e6..9a46fac83ef2b3b80427dbf8fd412572a200ad04 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-04  Mark Wielaard  <mjw@redhat.com>
+
+       * dwarf_siblingof.c (dwarf_siblingof): Check sibling attribute
+       is after current DIE.
+
 2015-01-04  Mark Wielaard  <mjw@redhat.com>
 
        * cfi.c (enough_registers): Check reg < INT32_MAX / sizeof
index f8241b37738607a922bdefc5385db3bc422e67a6..e598ae4197797b3d29b9db0244be3c56cf64a1be 100644 (file)
@@ -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 <drepper@redhat.com>, 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;