libdw: Break long or circular DIE ref chains in dwarf_[has]attr_integrate.
authorMark Wielaard <mark@klomp.org>
Sun, 10 Jun 2018 14:59:12 +0000 (16:59 +0200)
committerMark Wielaard <mark@klomp.org>
Mon, 11 Jun 2018 15:26:02 +0000 (17:26 +0200)
Bad DWARF could create a very long or circular DIE ref chain by linking
DW_AT_abstract_origin or DW_AT_specification to the DIE itself. Break
the chain after seeing a large number (16) of DIEs.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/ChangeLog
libdw/dwarf_attr_integrate.c
libdw/dwarf_hasattr_integrate.c

index 1195cf6..07a1346 100644 (file)
@@ -1,3 +1,9 @@
+2018-06-10  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf_attr_integrate.c (dwarf_attr_integrate): Stop after 16 DIE
+       ref chains.
+       * dwarf_hasattr_integrate.c (dwarf_hasattr_integrate): Likewise.
+
 2018-06-08  Mark Wielaard  <mark@klomp.org>
 
        * dwarf_getabbrev.c (dwarf_getabbrev): Check die and offset.
index 748d988..fc06863 100644 (file)
@@ -38,7 +38,7 @@ dwarf_attr_integrate (Dwarf_Die *die, unsigned int search_name,
                      Dwarf_Attribute *result)
 {
   Dwarf_Die die_mem;
-
+  int chain = 16; /* Largest DIE ref chain we will follow.  */
   do
     {
       Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, search_name, result);
@@ -53,7 +53,7 @@ dwarf_attr_integrate (Dwarf_Die *die, unsigned int search_name,
 
       die = INTUSE(dwarf_formref_die) (attr, &die_mem);
     }
-  while (die != NULL);
+  while (die != NULL && chain-- != 0);
 
   /* Not NULL if it didn't have abstract_origin and specification
      attributes.  If it is a split CU then see if the skeleton
index 4d4b4c5..1d94628 100644 (file)
@@ -37,7 +37,7 @@ int
 dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name)
 {
   Dwarf_Die die_mem;
-
+  int chain = 16; /* Largest DIE ref chain we will follow.  */
   do
     {
       if (INTUSE(dwarf_hasattr) (die, search_name))
@@ -53,7 +53,7 @@ dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name)
 
       die = INTUSE(dwarf_formref_die) (attr, &die_mem);
     }
-  while (die != NULL);
+  while (die != NULL && chain-- != 0);
 
   /* Not NULL if it didn't have abstract_origin and specification
      attributes.  If it is a split CU then see if the skeleton