Commit bf6199ec by Harald Anlauf

PR fortran/95091 - Buffer overflows with submodules and long symbols

With submodules, name mangling results in long internal symbols.  This
requires adjustment of the sizes of temporaries to avoid buffer overflows.

2020-06-07  Harald Anlauf  <anlauf@gmx.de>

gcc/fortran/
	PR fortran/95091
	* class.c (get_unique_type_string, gfc_hash_value): Enlarge
	buffers, and check whether the strings returned by
	get_unique_type_string() fit.

(cherry picked from commit b342cfd648e6658363c7c8fef83af8f59dba1795)
parent 3e9261f0
...@@ -509,9 +509,11 @@ get_unique_type_string (char *string, gfc_symbol *derived) ...@@ -509,9 +509,11 @@ get_unique_type_string (char *string, gfc_symbol *derived)
static void static void
get_unique_hashed_string (char *string, gfc_symbol *derived) get_unique_hashed_string (char *string, gfc_symbol *derived)
{ {
/* Provide sufficient space to hold "symbol_Pdtsymbol". */ /* Provide sufficient space to hold "symbol.symbol_symbol". */
char tmp[2*GFC_MAX_SYMBOL_LEN+5]; char tmp[3*GFC_MAX_SYMBOL_LEN+3];
get_unique_type_string (&tmp[0], derived); get_unique_type_string (&tmp[0], derived);
size_t len = strnlen (tmp, sizeof (tmp));
gcc_assert (len < sizeof (tmp));
/* If string is too long, use hash value in hex representation (allow for /* If string is too long, use hash value in hex representation (allow for
extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab). extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
We need space to for 15 characters "__class_" + symbol name + "_%d_%da", We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
...@@ -532,12 +534,13 @@ unsigned int ...@@ -532,12 +534,13 @@ unsigned int
gfc_hash_value (gfc_symbol *sym) gfc_hash_value (gfc_symbol *sym)
{ {
unsigned int hash = 0; unsigned int hash = 0;
/* Provide sufficient space to hold "symbol_Pdtsymbol". */ /* Provide sufficient space to hold "symbol.symbol_symbol". */
char c[2*GFC_MAX_SYMBOL_LEN+5]; char c[3*GFC_MAX_SYMBOL_LEN+3];
int i, len; int i, len;
get_unique_type_string (&c[0], sym); get_unique_type_string (&c[0], sym);
len = strlen (c); len = strnlen (c, sizeof (c));
gcc_assert (len < sizeof (c));
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
hash = (hash << 6) + (hash << 16) - hash + c[i]; hash = (hash << 6) + (hash << 16) - hash + c[i];
......
! { dg-do compile }
! { dg-options "-fsecond-underscore" }
! PR fortran/95091 - ICE in gfc_hash_value
module m2345678901234567890123456789012345678901234567890123456789_123
type t2345678901234567890123456789012345678901234567890123456789_123
end type t2345678901234567890123456789012345678901234567890123456789_123
interface
module subroutine s2345678901234567890123456789012345678901234567890123456789_123 &
(x2345678901234567890123456789012345678901234567890123456789_123)
end
end interface
end
submodule(m2345678901234567890123456789012345678901234567890123456789_123) &
n2345678901234567890123456789012345678901234567890123456789_123
type, extends(t2345678901234567890123456789012345678901234567890123456789_123) :: &
u2345678901234567890123456789012345678901234567890123456789_123
end type
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment