PR24898, An out-of-bounds read occured in display_data
authorAlan Modra <amodra@gmail.com>
Mon, 19 Aug 2019 10:54:35 +0000 (20:24 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 19 Aug 2019 11:08:59 +0000 (20:38 +0930)
Given 32-bit pointers and a 64-bit bfd_size_type, it is relatively
easy to construct a value of augmentation_data_len (eg. 0x100000000)
that won't fail pointer checks but will print without bounds.

PR 24898
* dwarf.c (display_debug_frames): Use the read_cie check and error
for augmentation data length.

binutils/ChangeLog
binutils/dwarf.c

index 7605a4039567a5f63b12c840fc32c86277179b4d..f629282e47f0dce41d21de6f8b6bc44bbd268ccb 100644 (file)
@@ -1,3 +1,9 @@
+2019-08-19  Alan Modra  <amodra@gmail.com>
+
+       PR 24898
+       * dwarf.c (display_debug_frames): Use the read_cie check and error
+       for augmentation data length.
+
 2019-08-17  Alan Modra  <amodra@gmail.com>
 
        PR 24911
index b4738ebb8d3c9ce41456c78b4661732120189b01..e792a17018cc908bdc2af1ca397822cfad0e0260 100644 (file)
@@ -7822,18 +7822,18 @@ display_debug_frames (struct dwarf_section *section,
            {
              READ_ULEB (augmentation_data_len);
              augmentation_data = start;
-             start += augmentation_data_len;
              /* PR 17512 file: 722-8446-0.004 and PR 22386.  */
-             if (start >= end
-                 || ((bfd_signed_vma) augmentation_data_len) < 0
-                 || augmentation_data > start)
+             if (augmentation_data_len > (bfd_size_type) (end - start))
                {
-                 warn (_("Corrupt augmentation data length: 0x%s\n"),
-                       dwarf_vmatoa ("x", augmentation_data_len));
+                 warn (_("Augmentation data too long: 0x%s, "
+                         "expected at most %#lx\n"),
+                       dwarf_vmatoa ("x", augmentation_data_len),
+                       (unsigned long) (end - start));
                  start = end;
                  augmentation_data = NULL;
                  augmentation_data_len = 0;
                }
+             start += augmentation_data_len;
            }
 
          printf ("\n%08lx %s %s FDE cie=%08lx pc=",