From 35a335a159216548fc77263ac5df71ff29d3f448 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Thu, 25 Jun 2020 20:32:13 +0200 Subject: [PATCH] PR fortran/95826 - Buffer overflows with PDTs and long symbols With PDTs (parameterized derived types), name mangling results in variably long internal symbols. Use a dynamic buffer instead of a fixed-size one. gcc/fortran/ PR fortran/95826 * decl.c (gfc_match_decl_type_spec): Replace a fixed size buffer by a pointer and reallocate if necessary. --- gcc/fortran/decl.c | 8 +++++--- gcc/testsuite/gfortran.dg/pr95826.f90 | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr95826.f90 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index c27cfacf2e4..ac1f63f66e0 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -4095,7 +4095,7 @@ match gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) { /* Provide sufficient space to hold "pdtsymbol". */ - char name[GFC_MAX_SYMBOL_LEN + 1 + 3]; + char *name = XALLOCAVEC (char, GFC_MAX_SYMBOL_LEN + 1); gfc_symbol *sym, *dt_sym; match m; char c; @@ -4286,8 +4286,10 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type); ts->u.derived = sym; const char* lower = gfc_dt_lower_string (sym->name); - size_t len = strnlen (lower, sizeof (name)); - gcc_assert (len < sizeof (name)); + size_t len = strlen (lower); + /* Reallocate with sufficient size. */ + if (len > GFC_MAX_SYMBOL_LEN) + name = XALLOCAVEC (char, len + 1); memcpy (name, lower, len); name[len] = '\0'; } diff --git a/gcc/testsuite/gfortran.dg/pr95826.f90 b/gcc/testsuite/gfortran.dg/pr95826.f90 new file mode 100644 index 00000000000..8de04e65df0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr95826.f90 @@ -0,0 +1,20 @@ +! { dg-do compile } +! { dg-options "-fsecond-underscore" } +! PR fortran/95826 - ICE in gfc_match_decl_type_spec, at fortran/decl.c:4290 + +program p + type t2345678901234567890123456789012345678901234567890123456789_123 & + (a2345678901234567890123456789012345678901234567890123456789_123, & + b2345678901234567890123456789012345678901234567890123456789_123) + integer, kind :: & + a2345678901234567890123456789012345678901234567890123456789_123 + integer, len :: & + b2345678901234567890123456789012345678901234567890123456789_123 + end type + integer, parameter :: & + n2345678901234567890123456789012345678901234567890123456789_123 = 16 + type(t2345678901234567890123456789012345678901234567890123456789_123 & + (n2345678901234567890123456789012345678901234567890123456789_123,:)), & + allocatable :: & + x2345678901234567890123456789012345678901234567890123456789_123 +end -- 2.30.2