Commit 36442ee2 by Harald Anlauf

PR fortran/95530, PR fortran/95537 - Buffer overflows with long symbols

The testcases for PR95090 and PR95106 trigger buffer overflows with long
symbols that were found with an instrumented compiler.  Enlarge the
affected buffers, and add checks that the buffers will suffice.

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

gcc/fortran/
	PR fortran/95530
	PR fortran/95537
	* decl.c (gfc_match_decl_type_spec): Enlarge buffer, and enhance
	string copy to detect buffer overflow.
	* gfortran.h (gfc_common_head): Enlarge buffer.
	* trans-common.c (finish_equivalences): Enhance string copy to
	detect buffer overflow.

(cherry picked from commit bcd96c9cce962ca5b2c6f8459597fb759f945ccf)
parent b3c17dfe
...@@ -4079,7 +4079,8 @@ match_byte_typespec (gfc_typespec *ts) ...@@ -4079,7 +4079,8 @@ match_byte_typespec (gfc_typespec *ts)
match match
gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
{ {
char name[GFC_MAX_SYMBOL_LEN + 1]; /* Provide sufficient space to hold "pdtsymbol". */
char name[GFC_MAX_SYMBOL_LEN + 1 + 3];
gfc_symbol *sym, *dt_sym; gfc_symbol *sym, *dt_sym;
match m; match m;
char c; char c;
...@@ -4269,7 +4270,11 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) ...@@ -4269,7 +4270,11 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
return m; return m;
gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type); gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type);
ts->u.derived = sym; ts->u.derived = sym;
strcpy (name, gfc_dt_lower_string (sym->name)); const char* lower = gfc_dt_lower_string (sym->name);
size_t len = strnlen (lower, sizeof (name));
gcc_assert (len < sizeof (name));
memcpy (name, lower, len);
name[len] = '\0';
} }
if (sym && sym->attr.flavor == FL_STRUCT) if (sym && sym->attr.flavor == FL_STRUCT)
......
...@@ -1677,7 +1677,8 @@ typedef struct gfc_common_head ...@@ -1677,7 +1677,8 @@ typedef struct gfc_common_head
char use_assoc, saved, threadprivate; char use_assoc, saved, threadprivate;
unsigned char omp_declare_target : 1; unsigned char omp_declare_target : 1;
unsigned char omp_declare_target_link : 1; unsigned char omp_declare_target_link : 1;
char name[GFC_MAX_SYMBOL_LEN + 1]; /* Provide sufficient space to hold "symbol.eq.1234567890". */
char name[GFC_MAX_SYMBOL_LEN + 1 + 14];
struct gfc_symbol *head; struct gfc_symbol *head;
const char* binding_label; const char* binding_label;
int is_bind_c; int is_bind_c;
......
...@@ -1313,7 +1313,11 @@ finish_equivalences (gfc_namespace *ns) ...@@ -1313,7 +1313,11 @@ finish_equivalences (gfc_namespace *ns)
c->where = ns->proc_name->declared_at; c->where = ns->proc_name->declared_at;
else if (ns->is_block_data) else if (ns->is_block_data)
c->where = ns->sym_root->n.sym->declared_at; c->where = ns->sym_root->n.sym->declared_at;
strcpy (c->name, z->module);
size_t len = strlen (z->module);
gcc_assert (len < sizeof (c->name));
memcpy (c->name, z->module, len);
c->name[len] = '\0';
} }
else else
c = NULL; c = NULL;
......
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