Imported Upstream version 0.165
[platform/upstream/elfutils.git] / libdw / dwarf_getaranges.c
index 20ac7ec..4252746 100644 (file)
@@ -48,14 +48,13 @@ compare_aranges (const void *a, const void *b)
 {
   struct arangelist *const *p1 = a, *const *p2 = b;
   struct arangelist *l1 = *p1, *l2 = *p2;
-  return l1->arange.addr - l2->arange.addr;
+  if (l1->arange.addr != l2->arange.addr)
+    return (l1->arange.addr < l2->arange.addr) ? -1 : 1;
+  return 0;
 }
 
 int
-dwarf_getaranges (dbg, aranges, naranges)
-     Dwarf *dbg;
-     Dwarf_Aranges **aranges;
-     size_t *naranges;
+dwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges, size_t *naranges)
 {
   if (dbg == NULL)
     return -1;
@@ -108,10 +107,16 @@ dwarf_getaranges (dbg, aranges, naranges)
 
         5. A 1-byte unsigned integer containing the size in bytes of
         a segment descriptor on the target system.  */
+      if (unlikely (readp + 4 > readendp))
+       goto invalid;
+
       Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
       unsigned int length_bytes = 4;
       if (length == DWARF3_LENGTH_64_BIT)
        {
+         if (unlikely (readp + 8 > readendp))
+           goto invalid;
+
          length = read_8ubyte_unaligned_inc (dbg, readp);
          length_bytes = 8;
        }
@@ -119,6 +124,9 @@ dwarf_getaranges (dbg, aranges, naranges)
                         && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE))
        goto invalid;
 
+      if (unlikely (readp + 2 > readendp))
+       goto invalid;
+
       unsigned int version = read_2ubyte_unaligned_inc (dbg, readp);
       if (version != 2)
        {
@@ -134,14 +142,14 @@ dwarf_getaranges (dbg, aranges, naranges)
          return -1;
        }
 
-      Dwarf_Word offset;
+      Dwarf_Word offset = 0;
       if (__libdw_read_offset_inc (dbg,
                                   IDX_debug_aranges, &readp,
                                   length_bytes, &offset, IDX_debug_info, 4))
        goto fail;
 
       unsigned int address_size = *readp++;
-      if (address_size != 4 && address_size != 8)
+      if (unlikely (address_size != 4 && address_size != 8))
        goto invalid;
 
       /* We don't actually support segment selectors.  */
@@ -162,6 +170,9 @@ dwarf_getaranges (dbg, aranges, naranges)
                                        address_size, &range_address))
            goto fail;
 
+         if (readp + address_size > readendp)
+           goto invalid;
+
          if (address_size == 4)
            range_length = read_4ubyte_unaligned_inc (dbg, readp);
          else