Re: Fix an undefined behaviour in the BFD library's DWARF parser
authorAlan Modra <amodra@gmail.com>
Thu, 16 Dec 2021 00:20:58 +0000 (10:50 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 16 Dec 2021 04:08:47 +0000 (14:38 +1030)
Using an unsigned int cast (to 32 bits) on a pointer difference (of
possibly 64 bits) is wrong.  Even though it will work on all real
object files, the fuzzers will eventually find this hole.

PR 28687
* dwarf1.c (parse_die): Cast pointer difference to size_t.
Catch another possible pointer overflow.

bfd/dwarf1.c

index 9f4665501b44a45b7bc916e69872169e8257936d..6b95e57cae9bc48c1e1aeda12926471a3dbe3f1a 100644 (file)
@@ -193,8 +193,8 @@ parse_die (bfd *         abfd,
     return false;
   aDieInfo->length = bfd_get_32 (abfd, xptr);
   xptr += 4;
-  if (aDieInfo->length == 0
-      || this_die + aDieInfo->length > aDiePtrEnd)
+  if (aDieInfo->length <= 4
+      || (size_t) (aDiePtrEnd - this_die) < aDieInfo->length)
     return false;
   aDiePtrEnd = this_die + aDieInfo->length;
   if (aDieInfo->length < 6)
@@ -258,7 +258,7 @@ parse_die (bfd *         abfd,
          if (xptr + 2 <= aDiePtrEnd)
            {
              block_len = bfd_get_16 (abfd, xptr);
-             if ((unsigned int) (aDiePtrEnd - xptr) < block_len)
+             if ((size_t) (aDiePtrEnd - xptr) < block_len)
                return false;
              xptr += block_len;
            }
@@ -268,7 +268,7 @@ parse_die (bfd *         abfd,
          if (xptr + 4 <= aDiePtrEnd)
            {
              block_len = bfd_get_32 (abfd, xptr);
-             if ((unsigned int) (aDiePtrEnd - xptr) < block_len)
+             if ((size_t) (aDiePtrEnd - xptr) < block_len)
                return false;
              xptr += block_len;
            }