[binutils-gdb] buffer overflow in fetch_indexed_addr

Alan Modra amodra@sourceware.org
Thu Jun 18 06:02:26 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=69a6db768a5bec4bcef4855fa08ef15e13fc0488

commit 69a6db768a5bec4bcef4855fa08ef15e13fc0488
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Jun 18 15:11:53 2026 +0930

    buffer overflow in fetch_indexed_addr
    
    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.

Diff:
---
 binutils/dwarf.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 4720dd717fa..f915495f6b3 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -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;
     }


More information about the Binutils-cvs mailing list