]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
buffer overflow in fetch_indexed_addr
authorAlan Modra <amodra@gmail.com>
Thu, 18 Jun 2026 05:41:53 +0000 (15:11 +0930)
committerAlan Modra <amodra@gmail.com>
Thu, 18 Jun 2026 05:57:26 +0000 (15:27 +0930)
oss-fuzz found another case where sanity checks weren't good enough.

* dwarf.c (fetch_indexed_addr): Avoid integer overflow when
sanity checking field offset
(fetch_indexed_offset): Similarly.  Don't bother with "too small"
warning, which will be covered by field offset check.  Warn
about base and index rather than possibly overflowed calculation.

binutils/dwarf.c

index 4720dd717fadeb8cdce5ebe3bbfceca6761f2e90..f915495f6b3795ce6840c86670ec42cb81b3edc1 100644 (file)
@@ -744,7 +744,8 @@ fetch_indexed_addr (uint64_t offset, uint32_t num_bytes)
       return 0;
     }
 
-  if (offset + num_bytes > section->size)
+  if (offset > section->size
+      || num_bytes > section->size - offset)
     {
       warn (_("Offset into section %s too big: %#" PRIx64 "\n"),
            section->name, offset);
@@ -769,7 +770,7 @@ fetch_indexed_offset (uint64_t                         idx,
                      uint64_t                         base_address,
                      uint64_t                         offset_size)
 {
-  uint64_t offset_of_offset = base_address + idx * offset_size;
+  uint64_t offset_of_offset;
   struct dwarf_section *section = &debug_displays [sec_enum].section;
 
   if (section->start == NULL)
@@ -778,17 +779,13 @@ fetch_indexed_offset (uint64_t                         idx,
       return -1;
     }
 
-  if (section->size < 4)
-    {
-      warn (_("Section %s is too small to contain an value indexed from another section!\n"),
-           section->name);
-      return -1;
-    }
-
-  if (offset_of_offset + offset_size >= section->size)
+  if (_bfd_mul_overflow (idx, offset_size, &offset_of_offset)
+      || (offset_of_offset += base_address) < base_address
+      || offset_of_offset > section->size
+      || offset_size > section->size - offset_of_offset)
     {
-      warn (_("Offset of %#" PRIx64 " is too big for section %s\n"),
-           offset_of_offset, section->name);
+      warn (_("Base %#" PRIx64 " with index %#" PRIx64 " is too big for section %s\n"),
+           base_address, idx, section->name);
       return -1;
     }