From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 86595 invoked by alias); 12 Apr 2015 21:54:43 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 86567 invoked by uid 89); 12 Apr 2015 21:54:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=AWL,BAYES_20,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_PASS,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mta21.charter.net Received: from mta21.charter.net (HELO mta21.charter.net) (216.33.127.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 12 Apr 2015 21:54:42 +0000 Received: from imp09 ([10.20.200.9]) by mta21.charter.net (InterMail vM.8.01.05.09 201-2260-151-124-20120717) with ESMTP id <20150412215440.YIWL23400.mta21.charter.net@imp09>; Sun, 12 Apr 2015 17:54:40 -0400 Received: from mtaout006.msg.strl.va.charter.net ([68.114.190.31]) by imp09 with smtp.charter.net id F9ug1q0020h5dSU059ugH1; Sun, 12 Apr 2015 17:54:40 -0400 Received: from impout001 ([68.114.189.16]) by mtaout006.msg.strl.va.charter.net (InterMail vM.9.00.015.01 201-2473-143-101) with ESMTP id <20150412215440.UEJY22086.mtaout006.msg.strl.va.charter.net@impout001>; Sun, 12 Apr 2015 16:54:40 -0500 Received: from amda8.localdomain ([70.209.200.55]) by impout001 with charter.net id F9uf1q0081CCuLu019ufMW; Sun, 12 Apr 2015 16:54:40 -0500 X-Authority-Analysis: v=2.1 cv=OLGp3EqB c=1 sm=1 tr=0 a=Qqyr9EjPILNkLx1bqxU4qw==:117 a=Qqyr9EjPILNkLx1bqxU4qw==:17 a=hOpmn2quAAAA:8 a=FurB0epzNeMA:10 a=r77TgQKjGQsHNAKrUKIA:9 a=9iDbn-4jx3cA:10 a=cKsnjEOsciEA:10 a=gZbpxnkM3yUA:10 a=mDV3o1hIAAAA:8 a=Ny37Fi9VEcS_cWEOiEEA:9 a=1j_c9mzocITx3ntI:21 a=sTvNYkomnXTl0V5-:21 a=QEXdDO2ut3YA:10 a=qXBeJp9jEtGmgxV2GB4A:9 X-Auth-id: anZkZWxpc2xlQGNoYXJ0ZXIubmV0 Message-ID: <552AE99E.5030802@charter.net> Date: Sun, 12 Apr 2015 21:54:00 -0000 From: Jerry DeLisle User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: gfortran CC: gcc patches Subject: [patch, libgfortran] PR65089 FAIL: gfortran.dg/io_real_boz(2|_[45]).f90 when tested with -fsanitize=address Content-Type: multipart/mixed; boundary="------------070503080402040501020901" X-SW-Source: 2015-04/txt/msg00538.txt.bz2 This is a multi-part message in MIME format. --------------070503080402040501020901 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 924 Hi all, The attached patch fixes this bug. It also eliminates non-freed memory whenever a format error occurs. Particular important when the user has use IOSTAT and generate_error does not exit, but returns to continue program execution. Regression tested on x86-64 and tested with -fsanitize=address and valgrind on a number of existing test cases. Changelog is fairly clear I think. OK for trunk? Regards, Jerry 2015-04-12 Jerry DeLisle PR libgfortran/65089 * io/format.h (free_format): New function to free memory allocated for building format error messages. * io/format.c (format_error): Add checks before freeing memory to avoid potential segfaults and free formatting data when needed on error conditions. Always allocate and NULL terminate the string. * io/transfer.c (st_read_done, st_write_done): Use new free_format function to clean up memory allocations when done. --------------070503080402040501020901 Content-Type: text/x-patch; name="pr65089.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pr65089.diff" Content-length: 3932 Index: io/format.c =================================================================== --- io/format.c (revision 222011) +++ io/format.c (working copy) @@ -243,6 +243,18 @@ get_fnode (format_data *fmt, fnode **head, fnode * } +/* free_format()-- Free allocated format string. */ +void +free_format (st_parameter_dt *dtp) +{ + if ((dtp->common.flags & IOPARM_DT_HAS_FORMAT && dtp->format)) + { + free (dtp->format); + dtp->format = NULL; + } +} + + /* free_format_data()-- Free all allocated format data. */ void @@ -1145,7 +1157,8 @@ format_error (st_parameter_dt *dtp, const fnode *f p = strchr (buffer, '\0'); - memcpy (p, dtp->format, width); + if (dtp->format) + memcpy (p, dtp->format, width); p += width; *p++ = '\n'; @@ -1158,6 +1171,26 @@ format_error (st_parameter_dt *dtp, const fnode *f *p++ = '^'; *p = '\0'; + /* Cleanup any left over memory allocations before calling generate + error. */ + if (is_internal_unit (dtp)) + { + if (dtp->format != NULL) + { + free (dtp->format); + dtp->format = NULL; + } + + /* Leave these alone if IOSTAT was given because execution will + return from generate error in those cases. */ + if (!(dtp->common.flags & IOPARM_HAS_IOSTAT)) + { + free (dtp->u.p.fmt); + free_format_hash_table (dtp->u.p.current_unit); + free_internal_unit (dtp); + } + } + generate_error (&dtp->common, LIBERROR_FORMAT, buffer); } @@ -1218,13 +1251,10 @@ parse_format (st_parameter_dt *dtp) /* Not found so proceed as follows. */ - if (format_cache_ok) - { - char *fmt_string = xmalloc (dtp->format_len + 1); - memcpy (fmt_string, dtp->format, dtp->format_len); - dtp->format = fmt_string; - dtp->format[dtp->format_len] = '\0'; - } + char *fmt_string = xmalloc (dtp->format_len + 1); + memcpy (fmt_string, dtp->format, dtp->format_len); + dtp->format = fmt_string; + dtp->format[dtp->format_len] = '\0'; dtp->u.p.fmt = fmt = xmalloc (sizeof (format_data)); fmt->format_string = dtp->format; @@ -1256,19 +1286,13 @@ parse_format (st_parameter_dt *dtp) else fmt->error = "Missing initial left parenthesis in format"; - if (fmt->error) - { - format_error (dtp, NULL, fmt->error); - if (format_cache_ok) - free (dtp->format); - free_format_hash_table (dtp->u.p.current_unit); - return; - } - if (format_cache_ok) save_parsed_format (dtp); else dtp->u.p.format_not_saved = 1; + + if (fmt->error) + format_error (dtp, NULL, fmt->error); } Index: io/format.h =================================================================== --- io/format.h (revision 222011) +++ io/format.h (working copy) @@ -132,6 +132,9 @@ internal_proto(format_error); extern void free_format_data (struct format_data *); internal_proto(free_format_data); +extern void free_format (st_parameter_dt *); +internal_proto(free_format); + extern void free_format_hash_table (gfc_unit *); internal_proto(free_format_hash_table); Index: io/transfer.c =================================================================== --- io/transfer.c (revision 222011) +++ io/transfer.c (working copy) @@ -3711,9 +3711,15 @@ void st_read_done (st_parameter_dt *dtp) { finalize_transfer (dtp); + if (is_internal_unit (dtp) || dtp->u.p.format_not_saved) - free_format_data (dtp->u.p.fmt); + { + free_format_data (dtp->u.p.fmt); + free_format (dtp); + } + free_ionml (dtp); + if (dtp->u.p.current_unit != NULL) unlock_unit (dtp->u.p.current_unit); @@ -3764,8 +3770,13 @@ st_write_done (st_parameter_dt *dtp) } if (is_internal_unit (dtp) || dtp->u.p.format_not_saved) - free_format_data (dtp->u.p.fmt); + { + free_format_data (dtp->u.p.fmt); + free_format (dtp); + } + free_ionml (dtp); + if (dtp->u.p.current_unit != NULL) unlock_unit (dtp->u.p.current_unit); --------------070503080402040501020901--