summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_getmacros.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2015-04-21 15:46:01 +0200
committerMark Wielaard <[email protected]>2015-04-22 13:42:58 +0200
commitf98b99db09f80666d5cf491a2ce126a59af0fdb1 (patch)
tree1802645b64360e93dee2d8176c26e72edde45567 /libdw/dwarf_getmacros.c
parent587c4b3e94c6ef877137d067d5d0f574f69b1391 (diff)
libdw: Don't overflow stack with user defined macro attributes array.
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 <[email protected]>
Diffstat (limited to 'libdw/dwarf_getmacros.c')
-rw-r--r--libdw/dwarf_getmacros.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c
index f9f29961..740368ef 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
@@ -373,8 +388,11 @@ read_macros (Dwarf *dbg, int sec_index,
attributes[i].cu = &fake_cu;
size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp);
- if (len == (size_t) -1)
- return -1;
+ if (unlikely (len == (size_t) -1))
+ {
+ free (attributesp);
+ return -1;
+ }
readp += len;
}
@@ -385,7 +403,11 @@ read_macros (Dwarf *dbg, int sec_index,
.attributes = attributes,
};
- if (callback (&macro, arg) != DWARF_CB_OK)
+ int res = callback (&macro, arg);
+ if (unlikely (attributesp != NULL))
+ free (attributesp);
+
+ if (res != DWARF_CB_OK)
return readp - startp;
}