]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/dwarf.c
More fixes for memory access violations exposed by fuzzed binaries.
[thirdparty/binutils-gdb.git] / binutils / dwarf.c
index 5f953d5118703ec85aa374376223fcef313a1339..d744929c02d79cb363b9261d62659434395b4b2a 100644 (file)
@@ -5157,6 +5157,16 @@ frame_need_space (Frame_Chunk *fc, unsigned int reg)
   if (fc->ncols == 0)
     return -1;
 
+  /* PR 17512: file: 2844a11d.  */
+  if (fc->ncols > 1024)
+    {
+      error (_("Unfeasibly large register number: %u\n"), reg);
+      fc->ncols = 0;
+      /* FIXME: 1024 is an arbitrary limit.  Increase it if
+        we ever encounter a valid binary that exceeds it.  */
+      return -1;
+    }
+
   fc->col_type = (short int *) xcrealloc (fc->col_type, fc->ncols,
                                           sizeof (short int));
   fc->col_offset = (int *) xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
@@ -5590,7 +5600,8 @@ display_debug_frames (struct dwarf_section *section,
          mreg = max_regs > 0 ? max_regs - 1 : 0;
          if (mreg < fc->ra)
            mreg = fc->ra;
-         frame_need_space (fc, mreg);
+         if (frame_need_space (fc, mreg) < 0)
+           break;
          if (fc->fde_encoding)
            encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
 
@@ -5696,7 +5707,11 @@ display_debug_frames (struct dwarf_section *section,
                          mreg = max_regs > 0 ? max_regs - 1 : 0;
                          if (mreg < cie->ra)
                            mreg = cie->ra;
-                         frame_need_space (cie, mreg);
+                         if (frame_need_space (cie, mreg) < 0)
+                           {
+                             warn (_("Invalid max register\n"));
+                             break;
+                           }
                          if (cie->fde_encoding)
                            encoded_ptr_size
                              = size_of_encoded_value (cie->fde_encoding);
@@ -5716,7 +5731,11 @@ display_debug_frames (struct dwarf_section *section,
              fc->ncols = 0;
              fc->col_type = (short int *) xmalloc (sizeof (short int));
              fc->col_offset = (int *) xmalloc (sizeof (int));
-             frame_need_space (fc, max_regs > 0 ? max_regs - 1 : 0);
+             if (frame_need_space (fc, max_regs > 0 ? max_regs - 1 : 0) < 0)
+               {
+                 warn (_("Invalid max register\n"));
+                 break;
+               }
              cie = fc;
              fc->augmentation = "";
              fc->fde_encoding = 0;
@@ -5739,7 +5758,11 @@ display_debug_frames (struct dwarf_section *section,
              fc->cfa_reg = cie->cfa_reg;
              fc->cfa_offset = cie->cfa_offset;
              fc->ra = cie->ra;
-             frame_need_space (fc, max_regs > 0 ? max_regs - 1: 0);
+             if (frame_need_space (fc, max_regs > 0 ? max_regs - 1: 0) < 0)
+               {
+                 warn (_("Invalid max register\n"));
+                 break;
+               }
              fc->fde_encoding = cie->fde_encoding;
            }
 
@@ -5857,7 +5880,6 @@ display_debug_frames (struct dwarf_section *section,
                  break;
                case DW_CFA_restore_extended:
                  reg = LEB ();
-                 frame_need_space (fc, reg);
                  if (frame_need_space (fc, reg) >= 0)
                    fc->col_type[reg] = DW_CFA_undefined;
                  break;
@@ -6176,7 +6198,12 @@ display_debug_frames (struct dwarf_section *section,
                  fc->cfa_reg = rs->cfa_reg;
                  fc->ra = rs->ra;
                  fc->cfa_exp = rs->cfa_exp;
-                 frame_need_space (fc, rs->ncols - 1);
+                 if (frame_need_space (fc, rs->ncols - 1) < 0)
+                   {
+                     warn (_("Invalid column number in saved frame state"));
+                     fc->ncols = 0;
+                     break;
+                   }
                  memcpy (fc->col_type, rs->col_type, rs->ncols * sizeof (* rs->col_type));
                  memcpy (fc->col_offset, rs->col_offset,
                          rs->ncols * sizeof (* rs->col_offset));
@@ -6218,7 +6245,7 @@ display_debug_frames (struct dwarf_section *section,
 
            case DW_CFA_def_cfa_expression:
              ul = LEB ();
-             if (start >= block_end || start + ul > block_end)
+             if (start >= block_end || start + ul > block_end || start + ul < start)
                {
                  printf (_("  DW_CFA_def_cfa_expression: <corrupt len %lu>\n"), ul);
                  break;
@@ -6240,7 +6267,8 @@ display_debug_frames (struct dwarf_section *section,
              if (reg >= (unsigned int) fc->ncols)
                reg_prefix = bad_reg;
              /* PR 17512: file: 069-133014-0.006.  */
-             if (start >= block_end || start + ul > block_end)
+             /* PR 17512: file: 98c02eb4.  */
+             if (start >= block_end || start + ul > block_end || start + ul < start)
                {
                  printf (_("  DW_CFA_expression: <corrupt len %lu>\n"), ul);
                  break;
@@ -6263,7 +6291,7 @@ display_debug_frames (struct dwarf_section *section,
              ul = LEB ();
              if (reg >= (unsigned int) fc->ncols)
                reg_prefix = bad_reg;
-             if (start >= block_end || start + ul > block_end)
+             if (start >= block_end || start + ul > block_end || start + ul < start)
                {
                  printf ("  DW_CFA_val_expression: <corrupt len %lu>\n", ul);
                  break;
@@ -7189,76 +7217,76 @@ dwarf_select_sections_all (void)
 
 struct dwarf_section_display debug_displays[] =
 {
-  { { ".debug_abbrev",     ".zdebug_abbrev",   NULL, NULL, 0, 0, 0 },
+  { { ".debug_abbrev",     ".zdebug_abbrev",   NULL, NULL, 0, 0, 0, NULL },
     display_debug_abbrev,   &do_debug_abbrevs, 0 },
-  { { ".debug_aranges",            ".zdebug_aranges",  NULL, NULL, 0, 0, 0 },
+  { { ".debug_aranges",            ".zdebug_aranges",  NULL, NULL, 0, 0, 0, NULL },
     display_debug_aranges,  &do_debug_aranges, 1 },
-  { { ".debug_frame",       ".zdebug_frame",   NULL, NULL, 0, 0, 0 },
+  { { ".debug_frame",       ".zdebug_frame",   NULL, NULL, 0, 0, 0, NULL },
     display_debug_frames,   &do_debug_frames,  1 },
-  { { ".debug_info",       ".zdebug_info",     NULL, NULL, 0, 0, abbrev },
+  { { ".debug_info",       ".zdebug_info",     NULL, NULL, 0, 0, abbrev, NULL },
     display_debug_info,            &do_debug_info,     1 },
-  { { ".debug_line",       ".zdebug_line",     NULL, NULL, 0, 0, 0 },
+  { { ".debug_line",       ".zdebug_line",     NULL, NULL, 0, 0, 0, NULL },
     display_debug_lines,    &do_debug_lines,   1 },
-  { { ".debug_pubnames",    ".zdebug_pubnames",        NULL, NULL, 0, 0, 0 },
+  { { ".debug_pubnames",    ".zdebug_pubnames",        NULL, NULL, 0, 0, 0, NULL },
     display_debug_pubnames, &do_debug_pubnames,        0 },
-  { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0 },
+  { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0, NULL },
     display_debug_gnu_pubnames, &do_debug_pubnames, 0 },
-  { { ".eh_frame",         "",                 NULL, NULL, 0, 0, 0 },
+  { { ".eh_frame",         "",                 NULL, NULL, 0, 0, 0, NULL },
     display_debug_frames,   &do_debug_frames,  1 },
-  { { ".debug_macinfo",            ".zdebug_macinfo",  NULL, NULL, 0, 0, 0 },
+  { { ".debug_macinfo",            ".zdebug_macinfo",  NULL, NULL, 0, 0, 0, NULL },
     display_debug_macinfo,  &do_debug_macinfo, 0 },
-  { { ".debug_macro",      ".zdebug_macro",    NULL, NULL, 0, 0, 0 },
+  { { ".debug_macro",      ".zdebug_macro",    NULL, NULL, 0, 0, 0, NULL },
     display_debug_macro,    &do_debug_macinfo, 1 },
-  { { ".debug_str",        ".zdebug_str",      NULL, NULL, 0, 0, 0 },
+  { { ".debug_str",        ".zdebug_str",      NULL, NULL, 0, 0, 0, NULL },
     display_debug_str,     &do_debug_str,      0 },
-  { { ".debug_loc",        ".zdebug_loc",      NULL, NULL, 0, 0, 0 },
+  { { ".debug_loc",        ".zdebug_loc",      NULL, NULL, 0, 0, 0, NULL },
     display_debug_loc,     &do_debug_loc,      1 },
-  { { ".debug_pubtypes",    ".zdebug_pubtypes",        NULL, NULL, 0, 0, 0 },
+  { { ".debug_pubtypes",    ".zdebug_pubtypes",        NULL, NULL, 0, 0, 0, NULL },
     display_debug_pubnames, &do_debug_pubtypes,        0 },
-  { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0 },
+  { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0, NULL },
     display_debug_gnu_pubnames, &do_debug_pubtypes, 0 },
-  { { ".debug_ranges",     ".zdebug_ranges",   NULL, NULL, 0, 0, 0 },
+  { { ".debug_ranges",     ".zdebug_ranges",   NULL, NULL, 0, 0, 0, NULL },
     display_debug_ranges,   &do_debug_ranges,  1 },
-  { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0 },
+  { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0, NULL },
     display_debug_not_supported, NULL,         0 },
-  { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0 },
+  { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0, NULL },
     display_debug_not_supported, NULL,         0 },
-  { { ".debug_types",      ".zdebug_types",    NULL, NULL, 0, 0, abbrev },
+  { { ".debug_types",      ".zdebug_types",    NULL, NULL, 0, 0, abbrev, NULL },
     display_debug_types,    &do_debug_info,    1 },
-  { { ".debug_weaknames",   ".zdebug_weaknames", NULL, NULL, 0, 0, 0 },
+  { { ".debug_weaknames",   ".zdebug_weaknames", NULL, NULL, 0, 0, 0, NULL },
     display_debug_not_supported, NULL,         0 },
-  { { ".gdb_index",        "",                 NULL, NULL, 0, 0, 0 },
+  { { ".gdb_index",        "",                 NULL, NULL, 0, 0, 0, NULL },
     display_gdb_index,      &do_gdb_index,     0 },
-  { { ".trace_info",       "",                 NULL, NULL, 0, 0, trace_abbrev },
+  { { ".trace_info",       "",                 NULL, NULL, 0, 0, trace_abbrev, NULL },
     display_trace_info,            &do_trace_info,     1 },
-  { { ".trace_abbrev",     "",                 NULL, NULL, 0, 0, 0 },
+  { { ".trace_abbrev",     "",                 NULL, NULL, 0, 0, 0, NULL },
     display_debug_abbrev,   &do_trace_abbrevs, 0 },
-  { { ".trace_aranges",            "",                 NULL, NULL, 0, 0, 0 },
+  { { ".trace_aranges",            "",                 NULL, NULL, 0, 0, 0, NULL },
     display_debug_aranges,  &do_trace_aranges, 0 },
-  { { ".debug_info.dwo",    ".zdebug_info.dwo",        NULL, NULL, 0, 0, abbrev_dwo },
+  { { ".debug_info.dwo",    ".zdebug_info.dwo",        NULL, NULL, 0, 0, abbrev_dwo, NULL },
     display_debug_info,            &do_debug_info,     1 },
-  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_abbrev,   &do_debug_abbrevs, 0 },
-  { { ".debug_types.dwo",   ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo },
+  { { ".debug_types.dwo",   ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL },
     display_debug_types,    &do_debug_info,    1 },
-  { { ".debug_line.dwo",    ".zdebug_line.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_line.dwo",    ".zdebug_line.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_lines,    &do_debug_lines,   1 },
-  { { ".debug_loc.dwo",            ".zdebug_loc.dwo",  NULL, NULL, 0, 0, 0 },
+  { { ".debug_loc.dwo",            ".zdebug_loc.dwo",  NULL, NULL, 0, 0, 0, NULL },
     display_debug_loc,     &do_debug_loc,      1 },
-  { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_macro,    &do_debug_macinfo, 1 },
-  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_macinfo,  &do_debug_macinfo, 0 },
-  { { ".debug_str.dwo",     ".zdebug_str.dwo",  NULL, NULL, 0, 0, 0 },
+  { { ".debug_str.dwo",     ".zdebug_str.dwo",  NULL, NULL, 0, 0, 0, NULL },
     display_debug_str,      &do_debug_str,     1 },
-  { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0 },
+  { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0, NULL },
     display_debug_str_offsets, NULL,           0 },
-  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0 },
+  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0, NULL },
     display_debug_str_offsets, NULL,           0 },
-  { { ".debug_addr",       ".zdebug_addr",     NULL, NULL, 0, 0, 0 },
+  { { ".debug_addr",       ".zdebug_addr",     NULL, NULL, 0, 0, 0, NULL },
     display_debug_addr,     &do_debug_addr,    1 },
-  { { ".debug_cu_index",    "",                        NULL, NULL, 0, 0, 0 },
+  { { ".debug_cu_index",    "",                        NULL, NULL, 0, 0, 0, NULL },
     display_cu_index,       &do_debug_cu_index,        0 },
-  { { ".debug_tu_index",    "",                        NULL, NULL, 0, 0, 0 },
+  { { ".debug_tu_index",    "",                        NULL, NULL, 0, 0, 0, NULL },
     display_cu_index,       &do_debug_cu_index,        0 },
 };