gnu/gcc/eaf4292c83804bd21b920db174401ca3702601d4 Fortran: fix stack-buffer-overflow passing type to assumed-rank class [PR60576]
Two code paths copied a full GFC_MAX_DIMENSIONS dim[] array from a
descriptor that physically holds only dtype.rank dimensions, triggering
a stack-buffer-overflow detected by AddressSanitizer.
Case 1 - assumed-rank type(T) dummy passed to class(T) assumed-rank:
The caller only allocates storage for dtype.rank dimensions. The code
generated a static GFC_MAX_DIMENSIONS struct copy of the dim[] array,
reading past the physical end of the descriptor. Fix by checking
expr->rank == -1 and replacing the static copy with a runtime-sized
__builtin_memcpy of dtype.rank * sizeof(descriptor_dimension) bytes.
Case 2 - fixed-rank type(T) actual passed directly to class(T) assumed-rank:
gfortran uses a rank-specific descriptor type for fixed-rank type arrays
(dim[rank] rather than dim[GFC_MAX_DIMENSIONS]). The class assumed-rank
formal's descriptor has dim_t[GFC_MAX_DIMENSIONS]. The call to
gfc_class_array_data_assign with lhs_type=true keyed the ARRAY_RANGE_REF
off TREE_TYPE(lhs_dim) = dim_t[GFC_MAX_DIMENSIONS], reading 15*24 = 360
bytes from a descriptor that physically has only rank*24 bytes for the
dim[] array. Fix by checking CLASS_DATA(fsym)->as->rank == -1 and
passing lhs_type=false so the ARRAY_RANGE_REF is sized by
TREE_TYPE(rhs_dim) = dim_t[rank], copying only the physically present
entries. Fixed-rank class formals retain lhs_type=true.
Assisted by: Claude Sonnet 4.6
PR fortran/60576
gcc/fortran/ChangeLog:
PR fortran/60576
* trans-array.cc (gfc_conv_array_parameter): For an assumed-rank
actual argument passed to a CLASS assumed-rank formal, use a
runtime-sized memcpy for the dim[] entries instead of a full
GFC_MAX_DIMENSIONS static copy. For a fixed-rank actual to a
CLASS assumed-rank formal, pass lhs_type=false to
gfc_class_array_data_assign so the dim[] copy is sized by the
RHS descriptor type (dim_t[rank]). Fixed-rank class formals
retain lhs_type=true.
* trans-expr.cc (gfc_conv_derived_to_class): For an assumed-rank
actual, use a runtime-sized memcpy for the derived_array descriptor
dim[] copy instead of a full GFC_MAX_DIMENSIONS static copy.
gcc/testsuite/ChangeLog:
PR fortran/60576
* gfortran.dg/asan/assumed_rank_26.f90: New test covering both
assumed-rank and fixed-rank type actuals passed to a CLASS
assumed-rank dummy.
3 files changed