From patchwork Thu Aug 13 05:00:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Pluzhnikov X-Patchwork-Id: 506848 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 60F8514028F for ; Thu, 13 Aug 2015 15:01:16 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b=J0YuDVuv; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:from:date:message-id:subject:to :content-type; q=dns; s=default; b=VGXV8fbhD7HSqiWOHLMAL2lzBqzfH teT8rw0fVt08+YLtInytPl4lKYEaB22tDsJ0ItzlWl/9f5bH0qCx9C6IYOePbMA8 EZVeJt8FvYEwP0vea4YLArEptLkHXpPk2UBc7UVS4Sw4vxNp4GkR4dYmRukJOkg8 JklNRfSZo/NjuE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:from:date:message-id:subject:to :content-type; s=default; bh=awCTCmqosiJxQbCXmYxjMH2drik=; b=J0Y uDVuvQ47qlKk2Mj/VjR3dHAPADRpcEjZvxzip0+TwAJpRNODfDNpGuPnTIs4aWxX B1tXYrgGVJVyP9zV+EB6XXgX17ro0acU/YMo7dgspufcfVE+DPAJJ/6sJlECs54H 4F4ygPMBjVpYino0l+H1skWfRDp5NB3ROnCd+mAo= Received: (qmail 64579 invoked by alias); 13 Aug 2015 05:01:05 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 64445 invoked by uid 89); 13 Aug 2015 05:01:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-vk0-f46.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:sender:from:date:message-id:subject :to:content-type; bh=KZMLlJy5AvcH+N9Vfm0aA30gvxLvyufhSANt0B30UJA=; b=HhO3sAUg+RMK1E97aeA/w6zwxeEjF7v6IhWWku6E/gMK9I2rBXbcU++P/jCLy4eAf4 bQA1bGHFL0VjnNNr/cHFyuNMqDZUdZFIwlL0p4XZMf9nMfhTqZemwPwCDwMX+T1mwoUt ILvbuKOVZ1FvAW6FurARg9ge6oylYso6DxtfYS8RdnXY1pEPUVQtoOXY8M0EFfU/xceC KlFt6G9dXYJ+h8YPDMeUc60EDV2xeYZ6akTyaMcTk52eV8tGWrfSXs0NWw65bs1RB8kO 8G5yDYQ4eCQpbk11dnc3hChj14CMm7iuMNul6n3IVQCBDbcQxbGD098ZmwTTW0JlIRKJ Yykw== X-Gm-Message-State: ALoCoQlSUhY2wB8egOrk+STqmicN27N04TpFYZSa/TgTxFWo6wCkNMKIeobGQBt5Z8pat4y5QOne X-Received: by 10.52.227.99 with SMTP id rz3mr44493955vdc.47.1439442060660; Wed, 12 Aug 2015 22:01:00 -0700 (PDT) MIME-Version: 1.0 From: Paul Pluzhnikov Date: Wed, 12 Aug 2015 22:00:31 -0700 Message-ID: Subject: Fix BZ 18820 -- fmemopen may leak memory on failure To: GLIBC Devel Greetings, I split out the "fix leak" part of BZ #18757 fix from https://sourceware.org/ml/libc-alpha/2015-08/msg00315.html Tested on Linux/x86_64, no new failures. Thanks, 2015-08-12 Paul Pluzhnikov [BZ #18820] * libio/Makefile (test-fmemopen-mem): New test. * libio/test-fmemopen.c (do_bz18820): New test. * libio/fmemopen.c (__fmemopen): Fix memory leak. * libio/oldfmemopen.c (__old_fmemopen): Likewise. diff --git a/libio/Makefile b/libio/Makefile index 7b3bcf9..604f419 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -148,8 +148,10 @@ CFLAGS-tst_putwc.c = -DOBJPFX=\"$(objpfx)\" tst_wprintf2-ARGS = "Some Text" +test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace +generated += test-fmemopen.mtrace test-fmemopen.check generated += tst-fopenloc.mtrace tst-fopenloc.check aux := fileops genops stdfiles stdio strops @@ -164,7 +166,7 @@ shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \ oldiofsetpos64 ifeq ($(run-built-tests),yes) -tests-special += $(objpfx)test-freopen.out +tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out ifeq (yes,$(build-shared)) # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared # library is enabled since they depend on tst-fopenloc.out. @@ -184,6 +186,10 @@ $(objpfx)tst-fopenloc-cmp.out: ../iconvdata/testdata/ISO-8859-1..UTF8 \ cmp $^ > $@; \ $(evaluate-test) +$(objpfx)test-fmemopen-mem.out: $(objpfx)test-fmemopen.out + $(common-objpfx)malloc/mtrace $(objpfx)test-fmemopen.mtrace > $@; \ + $(evaluate-test) + $(objpfx)tst-fopenloc-mem.out: $(objpfx)tst-fopenloc.out $(common-objpfx)malloc/mtrace $(objpfx)tst-fopenloc.mtrace > $@; \ $(evaluate-test) diff --git a/libio/fmemopen.c b/libio/fmemopen.c index 3ab3e8d..66e2d83 100644 --- a/libio/fmemopen.c +++ b/libio/fmemopen.c @@ -149,6 +149,7 @@ __fmemopen (void *buf, size_t len, const char *mode) { cookie_io_functions_t iof; fmemopen_cookie_t *c; + FILE *result; c = (fmemopen_cookie_t *) calloc (sizeof (fmemopen_cookie_t), 1); if (c == NULL) @@ -209,7 +210,16 @@ __fmemopen (void *buf, size_t len, const char *mode) iof.seek = fmemopen_seek; iof.close = fmemopen_close; - return _IO_fopencookie (c, mode, iof); + result = _IO_fopencookie (c, mode, iof); + if (__glibc_unlikely (result == NULL)) + { + if (c->mybuffer) + free (c->buffer); + + free (c); + } + + return result; } libc_hidden_def (__fmemopen) versioned_symbol (libc, __fmemopen, fmemopen, GLIBC_2_22); diff --git a/libio/oldfmemopen.c b/libio/oldfmemopen.c index 8e35672..88ef8fa 100644 --- a/libio/oldfmemopen.c +++ b/libio/oldfmemopen.c @@ -204,6 +204,7 @@ __old_fmemopen (void *buf, size_t len, const char *mode) { cookie_io_functions_t iof; fmemopen_cookie_t *c; + FILE *result; if (__glibc_unlikely (len == 0)) { @@ -259,7 +260,16 @@ __old_fmemopen (void *buf, size_t len, const char *mode) iof.seek = fmemopen_seek; iof.close = fmemopen_close; - return _IO_fopencookie (c, mode, iof); + result = _IO_fopencookie (c, mode, iof); + if (__glibc_unlikely (result == NULL)) + { + if (c->mybuffer) + free (c->buffer); + + free (c); + } + + return result; } compat_symbol (libc, __old_fmemopen, fmemopen, GLIBC_2_2); #endif diff --git a/libio/test-fmemopen.c b/libio/test-fmemopen.c index 63ca89f..e8e757f 100644 --- a/libio/test-fmemopen.c +++ b/libio/test-fmemopen.c @@ -22,6 +22,32 @@ static char buffer[] = "foobar"; #include #include #include +#include + +static int +do_bz18820 (void) +{ + char ch; + FILE *stream; + + stream = fmemopen (&ch, 1, "?"); + if (stream) + { + printf ("fmemopen: expected NULL, got %p\n", stream); + fclose (stream); + return 1; + } + + stream = fmemopen (NULL, 42, "?"); + if (stream) + { + printf ("fmemopen: expected NULL, got %p\n", stream); + fclose (stream); + return 2; + } + + return 0; +} static int do_test (void) @@ -30,6 +56,8 @@ do_test (void) FILE *stream; int ret = 0; + mtrace (); + stream = fmemopen (buffer, strlen (buffer), "r+"); while ((ch = fgetc (stream)) != EOF) @@ -44,7 +72,7 @@ do_test (void) fclose (stream); - return ret; + return ret + do_bz18820 (); } #define TEST_FUNCTION do_test ()