PR25197, assertion fail coffgen.c
authorAlan Modra <amodra@gmail.com>
Tue, 19 Nov 2019 01:08:36 +0000 (11:38 +1030)
committerAlan Modra <amodra@gmail.com>
Tue, 19 Nov 2019 02:01:22 +0000 (12:31 +1030)
The testcase in this PR triggered "BFD_ASSERT (p2->is_sym)" by
sneakily generating a C_FILE sym whose value pointed into auxents.
The fix then is in the last changed line of this patch, to check
p->is_sym as well as p->u.syment.n_sclass.  The other changes fix
various overflow checks that weren't as solid as they could be.

PR 25197
* coffgen.c (coff_find_nearest_line_with_names): Check that C_FILE
u.syment.n_value does point at another C_FILE sym and not into
some auxent that happens to look like a C_FILE.  Properly check
for integer overflow and avoid possible pointer wrap-around.
Simplify pr17512 checks.

bfd/ChangeLog
bfd/coffgen.c

index d13d9695ff0243e1b507e02612818059b24a7307..ffe527c52a397e44f8f7a6e2a00e12e246a54b89 100644 (file)
@@ -1,3 +1,12 @@
+2019-11-19  Alan Modra  <amodra@gmail.com>
+
+       PR 25197
+       * coffgen.c (coff_find_nearest_line_with_names): Check that C_FILE
+       u.syment.n_value does point at another C_FILE sym and not into
+       some auxent that happens to look like a C_FILE.  Properly check
+       for integer overflow and avoid possible pointer wrap-around.
+       Simplify pr17512 checks.
+
 2019-11-19  Alan Modra  <amodra@gmail.com>
 
        PR 25200
index ba7bb5eaf42573668eedb8289816e721a129d928..7f26e18c4509167b54eac29046e47960211fdba1 100644 (file)
@@ -1814,10 +1814,11 @@ coff_get_normalized_symtab (bfd *abfd)
   if (! _bfd_coff_get_external_symbols (abfd))
     return NULL;
 
-  size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type);
+  size = obj_raw_syment_count (abfd);
   /* Check for integer overflow.  */
-  if (size < obj_raw_syment_count (abfd))
+  if (size > (bfd_size_type) -1 / sizeof (combined_entry_type))
     return NULL;
+  size *= sizeof (combined_entry_type);
   internal = (combined_entry_type *) bfd_zalloc (abfd, size);
   if (internal == NULL && size != 0)
     return NULL;
@@ -1844,29 +1845,20 @@ coff_get_normalized_symtab (bfd *abfd)
       symbol_ptr = internal_ptr;
       internal_ptr->is_sym = TRUE;
 
-      /* PR 17512: file: 1353-1166-0.004.  */
-      if (symbol_ptr->u.syment.n_sclass == C_FILE
-         && symbol_ptr->u.syment.n_numaux > 0
-         && raw_src + symesz + symbol_ptr->u.syment.n_numaux
-         * symesz > raw_end)
-       {
-         bfd_release (abfd, internal);
-         return NULL;
-       }
-
       for (i = 0;
           i < symbol_ptr->u.syment.n_numaux;
           i++)
        {
          internal_ptr++;
+         raw_src += symesz;
+
          /* PR 17512: Prevent buffer overrun.  */
-         if (internal_ptr >= internal_end)
+         if (raw_src >= raw_end || internal_ptr >= internal_end)
            {
              bfd_release (abfd, internal);
              return NULL;
            }
 
-         raw_src += symesz;
          bfd_coff_swap_aux_in (abfd, (void *) raw_src,
                                symbol_ptr->u.syment.n_type,
                                symbol_ptr->u.syment.n_sclass,
@@ -2408,13 +2400,16 @@ coff_find_nearest_line_with_names (bfd *abfd,
              maxdiff = offset + sec_vma - p2->u.syment.n_value;
            }
 
+         if (p->u.syment.n_value >= cof->raw_syment_count)
+           break;
+
          /* Avoid endless loops on erroneous files by ensuring that
             we always move forward in the file.  */
          if (p >= cof->raw_syments + p->u.syment.n_value)
            break;
 
          p = cof->raw_syments + p->u.syment.n_value;
-         if (p > pend || p->u.syment.n_sclass != C_FILE)
+         if (!p->is_sym || p->u.syment.n_sclass != C_FILE)
            break;
        }
     }
This page took 0.026735 seconds and 4 git commands to generate.