aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorHarald Anlauf <anlauf@gmx.de>2020-06-05 20:30:34 +0200
committerHarald Anlauf <anlauf@gmx.de>2020-06-05 20:30:34 +0200
commitbcd96c9cce962ca5b2c6f8459597fb759f945ccf (patch)
treeb6cbc17be1ba2a7c27d6d2c462b85a31da62f251 /gcc
parent608832716e27ca356ee38d14ae30b3ab525884ea (diff)
downloadgcc-bcd96c9cce962ca5b2c6f8459597fb759f945ccf.zip
gcc-bcd96c9cce962ca5b2c6f8459597fb759f945ccf.tar.gz
gcc-bcd96c9cce962ca5b2c6f8459597fb759f945ccf.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/decl.c9
-rw-r--r--gcc/fortran/gfortran.h3
-rw-r--r--gcc/fortran/trans-common.c6
3 files changed, 14 insertions, 4 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 3ad5559..1c1626d 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -4094,7 +4094,8 @@ match_byte_typespec (gfc_typespec *ts)
match
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;
match m;
char c;
@@ -4284,7 +4285,11 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
return m;
gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type);
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)
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 5af4484..0ef7b1b 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1677,7 +1677,8 @@ typedef struct gfc_common_head
char use_assoc, saved, threadprivate;
unsigned char omp_declare_target : 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;
const char* binding_label;
int is_bind_c;
diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c
index 3775a8b..1acc336 100644
--- a/gcc/fortran/trans-common.c
+++ b/gcc/fortran/trans-common.c
@@ -1314,7 +1314,11 @@ finish_equivalences (gfc_namespace *ns)
c->where = ns->proc_name->declared_at;
else if (ns->is_block_data)
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
c = NULL;