The initial patch for this PR had some fallout which for unknown reason
did only show up on i686, but not on x86_64.  With initial guidance by
Manfred Schwarb three further locations exhibiting buffer overrun could
be identified in a gdb session and were fixed.

Committed as 'obvious' to master.

Thanks,
Harald


PR fortran/95090 - ICE: identifier overflow

The initial fix for this PR uncovered several latent issues with further
too small string buffers which showed up only when testing on i686.
Provide sufficiently large temporaries.

2020-05-29  Harald Anlauf  <anl...@gmx.de>

gcc/fortran/
        PR fortran/95090
        * class.c (get_unique_type_string): Enlarge temporary for
        name-mangling.  Use strncpy to prevent buffer overrun.
        (get_unique_hashed_string): Enlarge temporary.
        (gfc_hash_value): Enlarge temporary for name-mangling.
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 9aa3eb7282c..db395624a16 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -479,11 +479,12 @@ gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
 static void
 get_unique_type_string (char *string, gfc_symbol *derived)
 {
-  char dt_name[GFC_MAX_SYMBOL_LEN+1];
+  /* Provide sufficient space to hold "Pdtsymbol".  */
+  char dt_name[GFC_MAX_SYMBOL_LEN+4];
   if (derived->attr.unlimited_polymorphic)
     strcpy (dt_name, "STAR");
   else
-    strcpy (dt_name, gfc_dt_upper_string (derived->name));
+    strncpy (dt_name, gfc_dt_upper_string (derived->name), sizeof (dt_name));
   if (derived->attr.unlimited_polymorphic)
     sprintf (string, "_%s", dt_name);
   else if (derived->module)
@@ -501,7 +502,8 @@ get_unique_type_string (char *string, gfc_symbol *derived)
 static void
 get_unique_hashed_string (char *string, gfc_symbol *derived)
 {
-  char tmp[2*GFC_MAX_SYMBOL_LEN+2];
+  /* Provide sufficient space to hold "symbol_Pdtsymbol".  */
+  char tmp[2*GFC_MAX_SYMBOL_LEN+5];
   get_unique_type_string (&tmp[0], derived);
   /* If string is too long, use hash value in hex representation (allow for
      extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
@@ -523,7 +525,8 @@ unsigned int
 gfc_hash_value (gfc_symbol *sym)
 {
   unsigned int hash = 0;
-  char c[2*(GFC_MAX_SYMBOL_LEN+1)];
+  /* Provide sufficient space to hold "symbol_Pdtsymbol".  */
+  char c[2*GFC_MAX_SYMBOL_LEN+5];
   int i, len;

   get_unique_type_string (&c[0], sym);

Reply via email to