]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/coffgrok.c
libctf: lookup_by_name: do not return success for nonexistent pointer types
[thirdparty/binutils-gdb.git] / binutils / coffgrok.c
index a4c9d544948c528ce87ccffa420ef887d14ca680..7b8dcf61b56bd3e7cd11af9265f0979e627246c7 100644 (file)
@@ -1,5 +1,5 @@
 /* coffgrok.c
-   Copyright (C) 1994-2015 Free Software Foundation, Inc.
+   Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
@@ -145,7 +145,7 @@ do_sections_p1 (struct coff_ofile *head)
       if (strcmp (section->name, ".bss") == 0)
        head->sections[i].data = 1;
       head->sections[i].address = section->lma;
-      head->sections[i].size = bfd_get_section_size (section);
+      head->sections[i].size = bfd_section_size (section);
       head->sections[i].number = idx;
       head->sections[i].nrelocs = section->reloc_count;
       head->sections[i].relocs =
@@ -424,11 +424,20 @@ do_type (unsigned int i)
       if (sym->n_numaux)
        {
          if (aux == NULL)
-           fatal (_("Aggregate definition needs auxillary information"));
+           fatal (_("Aggregate definition needs auxiliary information"));
 
          if (aux->x_sym.x_tagndx.p)
            {
-             unsigned int idx = INDEXOF (aux->x_sym.x_tagndx.p);
+             unsigned int idx;
+
+             /* PR 17512: file: e72f3988.  */
+             if (aux->x_sym.x_tagndx.l < 0 || aux->x_sym.x_tagndx.p < rawsyms)
+               {
+                 non_fatal (_("Invalid tag index %#lx encountered"), aux->x_sym.x_tagndx.l);
+                 idx = 0;
+               }
+             else
+               idx = INDEXOF (aux->x_sym.x_tagndx.p);
 
              if (idx >= rawcount)
                {
@@ -465,7 +474,7 @@ do_type (unsigned int i)
       break;
     case T_ENUM:
       if (aux == NULL)
-       fatal (_("Enum definition needs auxillary information"));
+       fatal (_("Enum definition needs auxiliary information"));
       if (aux->x_sym.x_tagndx.p)
        {
          unsigned int idx = INDEXOF (aux->x_sym.x_tagndx.p);
@@ -476,7 +485,11 @@ do_type (unsigned int i)
          /* Referring to a enum defined elsewhere.  */
          res->type = coff_enumref_type;
          res->u.aenumref.ref = tindex[idx];
-         res->size = res->u.aenumref.ref->type->size;
+         /* PR 17512: file: b85b67e8.  */
+         if (res->u.aenumref.ref)
+           res->size = res->u.aenumref.ref->type->size;
+         else
+           res->size = 0;
        }
       else
        {
@@ -504,14 +517,24 @@ do_type (unsigned int i)
            int els;
 
            if (aux == NULL)
-             fatal (_("Array definition needs auxillary information"));
+             fatal (_("Array definition needs auxiliary information"));
            els = (dimind < DIMNUM
                   ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind]
                   : 0);
 
            ++dimind;
            ptr->type = coff_array_type;
-           ptr->size = els * res->size;
+           /* PR 17512: file: ae1971e2.
+              Check for integer overflow.  */
+           {
+             long long a, z;
+             a = els;
+             z = res->size;
+             a *= z;
+             ptr->size = (int) a;
+             if (ptr->size != a)
+               non_fatal (_("Out of range sum for els (%#x) * size (%#x)"), els, res->size);
+           }
            ptr->u.array.dim = els;
            ptr->u.array.array_of = res;
            res = ptr;
@@ -665,7 +688,22 @@ do_define (unsigned int i, struct coff_scope *b)
          if (!is->init)
            {
              is->low = s->where->offset;
-             is->high = s->where->offset + s->type->size;
+             /* PR 17512: file: 37e7a80d.
+                Check for integer overflow computing low + size.  */
+             {
+               long long a, z;
+
+               a = s->where->offset;
+               z = s->type->size;
+               a += z;
+               is->high = (int) a;
+               if (a != is->high)
+                 non_fatal (_("Out of range sum for offset (%#x) + size (%#x)"),
+                            is->low, s->type->size);
+             }
+             /* PR 17512: file: 37e7a80d.  */
+             if (is->high < s->where->offset)
+               fatal (_("Out of range type size: %u"), s->type->size);
              is->init = 1;
              is->parent = s->where->section;
            }
@@ -740,7 +778,11 @@ doit (void)
                /* PR 17512: file: 0ef7fbaf.  */
                if (last_function_type)
                  last_function_type->u.function.code = top_scope;
-               top_scope->sec = ofile->sections + sym->n_scnum;
+               /* PR 17512: file: 22908266.  */
+               if (sym->n_scnum < ofile->nsections && sym->n_scnum >= 0)
+                 top_scope->sec = ofile->sections + sym->n_scnum;
+               else
+                 top_scope->sec = NULL;
                top_scope->offset = sym->n_value;
              }
            else
@@ -750,7 +792,6 @@ doit (void)
                  fatal (_("Function start encountered without a top level scope."));
                top_scope->size = sym->n_value - top_scope->offset + 1;
                pop_scope ();
-
              }
            i += sym->n_numaux + 1;
          }
@@ -764,7 +805,11 @@ doit (void)
              {
                /* Block start.  */
                push_scope (1);
-               top_scope->sec = ofile->sections + sym->n_scnum;
+               /* PR 17512: file: af7e8e83.  */
+               if (sym->n_scnum < ofile->nsections && sym->n_scnum >= 0)
+                 top_scope->sec = ofile->sections + sym->n_scnum;
+               else
+                 top_scope->sec = NULL;
                top_scope->offset = sym->n_value;
              }
            else
@@ -801,13 +846,13 @@ doit (void)
        case C_UNTAG:
          /* Various definition.  */
          if (top_scope == NULL)
-           fatal (_("Aggregate defintion encountered without a scope"));
+           fatal (_("Aggregate definition encountered without a scope"));
          i = do_define (i, top_scope);
          break;
        case C_EXT:
        case C_LABEL:
          if (file_scope == NULL)
-           fatal (_("Label defintion encountered without a file scope"));
+           fatal (_("Label definition encountered without a file scope"));
          i = do_define (i, file_scope);
          break;
        case C_STAT:
@@ -815,7 +860,7 @@ doit (void)
        case C_AUTO:
        case C_REG:
          if (top_scope == NULL)
-           fatal (_("Variable defintion encountered without a scope"));
+           fatal (_("Variable definition encountered without a scope"));
          i = do_define (i, top_scope);
          break;
        case C_EOS:
@@ -841,16 +886,16 @@ coff_grok (bfd *inabfd)
       non_fatal (_("%s: is not a COFF format file"), bfd_get_filename (abfd));
       return NULL;
     }
-  
+
   storage = bfd_get_symtab_upper_bound (abfd);
 
   if (storage < 0)
-    bfd_fatal (abfd->filename);
+    bfd_fatal (bfd_get_filename (abfd));
 
   syms = (asymbol **) xmalloc (storage);
   symcount = bfd_canonicalize_symtab (abfd, syms);
   if (symcount < 0)
-    bfd_fatal (abfd->filename);
+    bfd_fatal (bfd_get_filename (abfd));
   rawsyms = obj_raw_syments (abfd);
   rawcount = obj_raw_syment_count (abfd);
   tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount));