From: Mark Wielaard Date: Sun, 4 Jan 2015 23:03:03 +0000 (+0100) Subject: libdw: Check DW_AT_sibling attribute offset is after current DIE. X-Git-Tag: elfutils-0.162~132 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=43e924ee0bb01576cb30a7069ad9183e55b1093b;p=thirdparty%2Felfutils.git 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 --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index b3093a16c..9a46fac83 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2015-01-04 Mark Wielaard + + * dwarf_siblingof.c (dwarf_siblingof): Check sibling attribute + is after current DIE. + 2015-01-04 Mark Wielaard * cfi.c (enough_registers): Check reg < INT32_MAX / sizeof diff --git a/libdw/dwarf_siblingof.c b/libdw/dwarf_siblingof.c index f8241b377..e598ae419 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 , 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;