]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Re: PR31692, objdump fails .debug_info size check
authorAlan Modra <amodra@gmail.com>
Fri, 10 May 2024 12:45:06 +0000 (22:15 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 10 May 2024 13:47:03 +0000 (23:17 +0930)
The fuzzers found a hole.  bfd_section_size_insane doesn't check
!SEC_HAS_CONTENTS sections against file size for obvious reasons,
which allows fuzzed debug sections to be stupidly large.  Real debug
sections of course always have contents.

PR 31692
* objdump.c (load_specific_debug_section): Don't allow sections
without contents.

binutils/objdump.c

index 3d70df470f290f7e4dc46cf80bc075f3015e6c14..7182abdab98fe62fb4d91d66b233398a3504470c 100644 (file)
@@ -4307,41 +4307,45 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
       return false;
     }
 
-  section->start = contents = xmalloc (alloced);
-  /* Ensure any string section has a terminating NUL.  */
-  section->start[section->size] = 0;
-
-  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
-      && debug_displays [debug].relocate)
-    {
-      ret = bfd_simple_get_relocated_section_contents (abfd,
-                                                      sec,
-                                                      section->start,
-                                                      syms) != NULL;
-      if (ret)
-       {
-         long reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
+  ret = false;
+  if ((sec->flags & SEC_HAS_CONTENTS) != 0)
+    {
+      section->start = contents = xmalloc (alloced);
+      /* Ensure any string section has a terminating NUL.  */
+      section->start[section->size] = 0;
 
-         if (reloc_size > 0)
+      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
+         && debug_displays [debug].relocate)
+       {
+         ret = bfd_simple_get_relocated_section_contents (abfd,
+                                                          sec,
+                                                          section->start,
+                                                          syms) != NULL;
+         if (ret)
            {
-             long reloc_count;
-             arelent **relocs;
+             long reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
 
-             relocs = (arelent **) xmalloc (reloc_size);
-
-             reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms);
-             if (reloc_count <= 0)
-               free (relocs);
-             else
+             if (reloc_size > 0)
                {
-                 section->reloc_info = relocs;
-                 section->num_relocs = reloc_count;
+                 long reloc_count;
+                 arelent **relocs;
+
+                 relocs = (arelent **) xmalloc (reloc_size);
+
+                 reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms);
+                 if (reloc_count <= 0)
+                   free (relocs);
+                 else
+                   {
+                     section->reloc_info = relocs;
+                     section->num_relocs = reloc_count;
+                   }
                }
            }
        }
+      else
+       ret = bfd_get_full_section_contents (abfd, sec, &contents);
     }
-  else
-    ret = bfd_get_full_section_contents (abfd, sec, &contents);
 
   if (!ret)
     {