display_loc_list
authorAlan Modra <amodra@gmail.com>
Sat, 15 May 2021 05:40:44 +0000 (15:10 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 15 May 2021 05:43:45 +0000 (15:13 +0930)
* dwarf.c (display_loc_list): Avoid pointer UB.  Correct check
before reading uleb length.  Warn on excess length.

binutils/ChangeLog
binutils/dwarf.c

index 1926afbdcf76a5123d365084cd179a9703437af3..9301a80e90f4ca6ce0b69a9a24414abc48221cb5 100644 (file)
@@ -1,3 +1,8 @@
+2021-05-15  Alan Modra  <amodra@gmail.com>
+
+       * dwarf.c (display_loc_list): Avoid pointer UB.  Correct check
+       before reading uleb length.  Warn on excess length.
+
 2021-05-15  Alan Modra  <amodra@gmail.com>
 
        * dwarf.c (display_debug_macro): Print strings that might not
index 68732cf491b7852285d590344f4535f1ea3fc036..4d29591faa699b2927367e8a10ff1bea119c2595 100644 (file)
@@ -6355,7 +6355,7 @@ display_loc_list (struct dwarf_section *section,
       dwarf_vma off = offset + (start - *start_ptr);
       dwarf_vma vbegin = vm1, vend = vm1;
 
-      if (start + 2 * pointer_size > section_end)
+      if (2 * pointer_size > (size_t) (section_end - start))
        {
          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
                (unsigned long) offset);
@@ -6408,7 +6408,7 @@ display_loc_list (struct dwarf_section *section,
                  (unsigned long) off, 8, "");
        }
 
-      if (start + 2 > section_end)
+      if (2 > (size_t) (section_end - start))
        {
          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
                (unsigned long) offset);
@@ -6417,7 +6417,7 @@ display_loc_list (struct dwarf_section *section,
 
       SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
 
-      if (start + length > section_end)
+      if (length > (size_t) (section_end - start))
        {
          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
                (unsigned long) offset);
@@ -6579,15 +6579,21 @@ display_loclists_list (struct dwarf_section *section,
          && llet != DW_LLE_start_length)
        continue;
 
-      if (start + 2 > section_end)
+      if (start == section_end)
        {
          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
                (unsigned long) offset);
          break;
        }
-
       READ_ULEB (length, start, section_end);
 
+      if (length > (size_t) (section_end - start))
+       {
+         warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
+               (unsigned long) offset);
+         break;
+       }
+
       print_dwarf_vma (begin, pointer_size);
       print_dwarf_vma (end, pointer_size);
 
@@ -6751,7 +6757,7 @@ display_loc_list_dwo (struct dwarf_section *section,
          return;
        }
 
-      if (start + 2 > section_end)
+      if (2 > (size_t) (section_end - start))
        {
          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
                (unsigned long) offset);
@@ -6759,7 +6765,7 @@ display_loc_list_dwo (struct dwarf_section *section,
        }
 
       SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
-      if (start + length > section_end)
+      if (length > (size_t) (section_end - start))
        {
          warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
                (unsigned long) offset);