Hi,

a common malloc() pattern is "malloc(num_foo * sizeof(foo_t)", that
is, create space for an array of type foo_t with num_foo elements.
There is a slight danger here in that the multiplication can overflow
and wrap around, and then the caller thinks it has a larger array than
what malloc has actually created. The attached patch changes the
libgfortran xmalloc() function to have an API similar to calloc() with
two arguments, and the implementation checks for wraparound.

(There are cases in libgfortran where space is allocated for temporary
multidimensional arrays. It might be useful to check for overflow when
multiplying the extent of each dimension, similar to how is done
inline for the ALLOCATE statement in addition to checking the final
multiplication with the size of each element as this patch
accomplishes.)

Tested on x86_64-unknown-linux-gnu, Ok for trunk?

2014-05-15  Janne Blomqvist  <j...@gcc.gnu.org>

    * libgfortran.h (xmalloc): Add size argument similar to calloc.
    * runtime/memory.c (xmalloc): Check for overflow.
    (xcalloc): Check for nonzero separately instead of multiplying.
    * generated/*.c: Regenerated.
    * intrinsics/cshift0.c (cshift0): Call updated xmalloc.
    * intrinsics/ctime.c (fdate): Likewise.
    (fdate_sub): Likewise.
    (ctime): Likewise.
    (ctime_sub): Likewise.
    * intrinsics/date_and_time.c (secnds): Likewise.
    * intrinsics/eoshift0.c (eoshift0): Likewise.
    * intrinsics/eoshift2.c (eoshift2): Likewise.
    * intrinsics/getcwd.c (getcwd): Likewise.
    * intrinsics/getlog.c (getlog): Likewise.
    * intrinsics/pack_generic.c (pack_internal): Likewise.
    (pack_s_internal): Likewise.
    * intrinsics/reshape_generic.c (reshape_internal): Likewise.
    * intrinsics/spread_generic.c (spread_internal): Likewise.
    (spread_internal_scalar): Likewise.
    * intrinsics/string_intrinsics_inc.c (string_trim): Likewise.
    (string_minmax): Likewise.
    * intrinsics/transpose_generic.c (transpose_internal): Likewise.
    * intrinsics/unpack_generic.c (unpack_internal): Likewise.
    * io/fbuf.c (fbuf_init): Likewise.
    * io/format.c (get_fnode): Likewise.
    (parse_format): Likewise.
    * io/intrinsics.c (ttynam): Likewise.
    * io/list_read.c (nml_touch_nodes): Likewise.
    (nml_read_obj): Likewise.
    * io/open.c (new_unit): Likewise.
    * io/transfer.c (st_set_nml_var): Likewise.
    * io/unit.c (get_internal_unit): Likewise.
    (init_units): Likewise.
    (filename_from_unit): Likewise.
    * io/unix.c (buf_init): Likewise.
    (tempfile_open): Likewise.
    * io/write.c (nml_write_obj): Likewise.
    * m4/bessel.m4 (bessel_jn_r'rtype_kind`): Likewise.
    (besse_yn_r'rtype_kind`): Likewise.
    * m4/cshift1.m4 (cshift1): Likewise.
    * m4/eoshift1.m4 (eoshift1): Likewise.
    * m4/eoshift3.m4 (eoshift3): Likewise.
    * m4/iforeach.m4: Likewise.
    * m4/ifunction.m4: Likewise.
    * m4/ifunction_logical.m4 (name`'rtype_qual`_'atype_code):
    Likewise.
    * m4/in_pack.m4 (internal_pack_'rtype_ccode`): Likewise.
    * m4/matmul.m4 (matmul_'rtype_code`): Likewise.
    * m4/matmull.m4 (matmul_'rtype_code`): Likewise.
    * m4/pack.m4 (pack_'rtype_code`): Likewise.
    * m4/reshape.m4 (reshape_'rtype_ccode`): Likewise.
    * m4/shape.m4 (shape_'rtype_kind`): Likewise.
    * m4/spread.m4 (spread_'rtype_code`): Likewise.
    (spread_scalar_'rtype_code`): Likewise.
    * m4/transpose.m4 (transpose_'rtype_code`): Likewise.
    * m4/unpack.m4 (unpack0_'rtype_code`): Likewise.
    (unpack1_'rtype_code`): Likewise.
    * runtime/convert_char.c (convert_char1_to_char4): Likewise.
    (convert_char4_to_char1): Likewise.
    * runtime/environ.c (init_unformatted): Likewise.
    * runtime/in_pack_generic.c (internal_pack): Likewise.


-- 
Janne Blomqvist

Attachment: xmalloc.diff.gz
Description: GNU Zip compressed data

Reply via email to