From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org
Subject: Re: Fix memory leak in __printf_fp_l (bug 26215)
Date: Thu, 9 Jul 2020 18:04:08 -0300 [thread overview]
Message-ID: <31f4ebeb-2ba5-d232-5905-235bc18b36be@linaro.org> (raw)
In-Reply-To: <alpine.DEB.2.21.2007091806270.14941@digraph.polyomino.org.uk>
On 09/07/2020 15:07, Joseph Myers wrote:
> __printf_fp_l has a memory leak in the case of some I/O errors, where
> both buffer and wbuffer have been malloced but the handling of I/O
> errors only frees wbuffer. This patch fixes this by moving the
> declaration of buffer to an outer scope and ensuring that it is freed
> when wbuffer is freed.
>
> Tested for x86_64 and x86.
LGTM, thanks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
>
> ---
>
> This patch is relative to a tree with my previous fix for bug 26214
> <https://sourceware.org/pipermail/libc-alpha/2020-July/116043.html>
> (pending review) applied.
>
> diff --git a/stdio-common/Makefile b/stdio-common/Makefile
> index dc3fd38a19..8475fd1f09 100644
> --- a/stdio-common/Makefile
> +++ b/stdio-common/Makefile
> @@ -68,7 +68,8 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
> scanf14a scanf16a \
> tst-printf-bz25691 \
> tst-vfprintf-width-prec-alloc \
> - tst-printf-fp-free
> + tst-printf-fp-free \
> + tst-printf-fp-leak
>
>
> test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble
Ok.
> @@ -80,12 +81,14 @@ tests-special += $(objpfx)tst-unbputc.out $(objpfx)tst-printf.out \
> $(objpfx)tst-vfprintf-width-prec-mem.out \
> $(objpfx)tst-printfsz-islongdouble.out \
> $(objpfx)tst-printf-bz25691-mem.out \
> - $(objpfx)tst-printf-fp-free-mem.out
> + $(objpfx)tst-printf-fp-free-mem.out \
> + $(objpfx)tst-printf-fp-leak-mem.out
> generated += tst-printf-bz18872.c tst-printf-bz18872.mtrace \
> tst-printf-bz18872-mem.out \
> tst-vfprintf-width-prec.mtrace tst-vfprintf-width-prec-mem.out \
> tst-printf-bz25691.mtrace tst-printf-bz25691-mem.out \
> - tst-printf-fp-free.mtrace tst-printf-fp-free-mem.out
> + tst-printf-fp-free.mtrace tst-printf-fp-free-mem.out \
> + tst-printf-fp-leak.mtrace tst-printf-fp-leak-mem.out
> endif
>
> tests-special += $(objpfx)tst-errno-manual.out
> @@ -113,6 +116,8 @@ tst-printf-bz25691-ENV = \
> MALLOC_TRACE=$(objpfx)tst-printf-bz25691.mtrace
> tst-printf-fp-free-ENV = \
> MALLOC_TRACE=$(objpfx)tst-printf-fp-free.mtrace
> +tst-printf-fp-leak-ENV = \
> + MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace
>
> $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
> $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' > $@; \
Ok.
> diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
> index 49c693575e..c0b79f2184 100644
> --- a/stdio-common/printf_fp.c
> +++ b/stdio-common/printf_fp.c
> @@ -72,7 +72,10 @@
> if (putc (outc, fp) == EOF) \
> { \
> if (buffer_malloced) \
> - free (wbuffer); \
> + { \
> + free (buffer); \
> + free (wbuffer); \
> + } \
> return -1; \
> } \
> ++done; \
> @@ -87,7 +90,10 @@
> if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen) \
> { \
> if (buffer_malloced) \
> - free (wbuffer); \
> + { \
> + free (buffer); \
> + free (wbuffer); \
> + } \
> return -1; \
> } \
> ptr += outlen; \
> @@ -110,7 +116,10 @@
> if (PAD (fp, ch, len) != len) \
> { \
> if (buffer_malloced) \
> - free (wbuffer); \
> + { \
> + free (buffer); \
> + free (wbuffer); \
> + } \
> return -1; \
> } \
> done += len; \
Ok.
> @@ -259,7 +268,8 @@ __printf_fp_l (FILE *fp, locale_t loc,
>
> /* Buffer in which we produce the output. */
> wchar_t *wbuffer = NULL;
> - /* Flag whether wbuffer is malloc'ed or not. */
> + char *buffer = NULL;
> + /* Flag whether wbuffer and buffer are malloc'ed or not. */
> int buffer_malloced = 0;
>
> p.expsign = 0;
> @@ -1172,7 +1182,6 @@ __printf_fp_l (FILE *fp, locale_t loc,
> PADN ('0', width);
>
> {
> - char *buffer = NULL;
> char *buffer_end = NULL;
> char *cp = NULL;
> char *tmpptr;
> @@ -1252,6 +1261,7 @@ __printf_fp_l (FILE *fp, locale_t loc,
> free (wbuffer);
> /* Avoid a double free if the subsequent PADN encounters an
> I/O error. */
> + buffer = NULL;
> wbuffer = NULL;
> }
> }
Ok.
> diff --git a/stdio-common/tst-printf-fp-leak.c b/stdio-common/tst-printf-fp-leak.c
> new file mode 100644
> index 0000000000..da11a486dd
> --- /dev/null
> +++ b/stdio-common/tst-printf-fp-leak.c
> @@ -0,0 +1,34 @@
> +/* Test memory leak in __printf_fp_l (bug 26215).
> + Copyright (C) 2020 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <mcheck.h>
> +#include <stdio.h>
> +#include <support/check.h>
> +
> +static int
> +do_test (void)
> +{
> + mtrace ();
> + FILE *fp = fopen ("/dev/full", "w");
> + TEST_VERIFY_EXIT (fp != NULL);
> + TEST_COMPARE (fprintf (fp, "%.65536f", 1.0), -1);
> + fclose (fp);
> + return 0;
> +}
> +
> +#include <support/test-driver.c>
>
Ok.
next prev parent reply other threads:[~2020-07-09 21:04 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-09 18:07 Joseph Myers
2020-07-09 21:04 ` Adhemerval Zanella [this message]
2020-07-10 7:20 ` Florian Weimer
2020-07-10 15:03 ` Joseph Myers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=31f4ebeb-2ba5-d232-5905-235bc18b36be@linaro.org \
--to=adhemerval.zanella@linaro.org \
--cc=libc-alpha@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).