]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Don't overflow stack with user defined macro attributes array.
authorMark Wielaard <mjw@redhat.com>
Tue, 21 Apr 2015 13:46:01 +0000 (15:46 +0200)
committerMark Wielaard <mjw@redhat.com>
Wed, 22 Apr 2015 11:42:58 +0000 (13:42 +0200)
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 <mjw@redhat.com>
libdw/ChangeLog
libdw/dwarf_getmacros.c

index 3abb38283922779563471412461c05d996e9ef65..87c7d821f891e9ccccde342780c0144fdb1bc84a 100644 (file)
@@ -1,3 +1,8 @@
+2015-04-21  Mark Wielaard  <mjw@redhat.com>
+
+       * dwarf_getmacros.c (read_macros): Allocate attributes dynamically
+       when there are more than 8.
+
 2015-04-01  Petr Machata  <pmachata@redhat.com>
 
        * libdwP.h (DWARF_E_NOT_CUDIE): New enumerator.
index f9f29961f6a234e1def6cf25adda3c4bcab0900b..740368ef09aa0cceaf2b2397beebd69422a3efc8 100644 (file)
@@ -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;
     }