In theory user defined debug macros can have an arbitrary number of arguments. Don't allocate them all on stack. If there are more than 8 (arbitrary number, but no sane macro should have more arguments), then dynamically allocate and free the attributes. Found by gcc -fsanitize=undefined. Which pointed out the nforms could be zero, creating an empty vla (which could cause undefined behavior). Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 5 +++++ libdw/dwarf_getmacros.c | 23 +++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 3abb382..87c7d82 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,8 @@ +2015-04-21 Mark Wielaard + + * dwarf_getmacros.c (read_macros): Allocate attributes dynamically + when there are more than 8. + 2015-04-01 Petr Machata * libdwP.h (DWARF_E_NOT_CUDIE): New enumerator. diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c index f9f2996..c5d47d6 100644 --- a/libdw/dwarf_getmacros.c +++ b/libdw/dwarf_getmacros.c @@ -361,7 +361,22 @@ read_macros (Dwarf *dbg, int sec_index, .endp = (void *) endp, }; - Dwarf_Attribute attributes[proto->nforms]; + Dwarf_Attribute *attributes; + Dwarf_Attribute *attributesp = NULL; + Dwarf_Attribute nattributes[8]; + if (unlikely (proto->nforms > 8)) + { + attributesp = malloc (sizeof (Dwarf_Attribute) * proto->nforms); + if (attributesp == NULL) + { + __libdw_seterrno (DWARF_E_NOMEM); + return -1; + } + attributes = attributesp; + } + else + attributes = &nattributes[0]; + for (Dwarf_Word i = 0; i < proto->nforms; ++i) { /* We pretend this is a DW_AT_GNU_macros attribute so that @@ -385,7 +400,11 @@ read_macros (Dwarf *dbg, int sec_index, .attributes = attributes, }; - if (callback (¯o, arg) != DWARF_CB_OK) + int res = callback (¯o, arg); + if (unlikely (attributesp != NULL)) + free (attributesp); + + if (res != DWARF_CB_OK) return readp - startp; } -- 2.1.0