From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2178) id A4225384D184; Tue, 30 Aug 2022 08:23:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A4225384D184 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1661847810; bh=7UHUL96oQRH26Q4qbiPzdIeIWUftuDdbjVgVzZDUoos=; h=From:To:Subject:Date:From; b=QVnuROao0VKnj9AjfE6Pm8Sy8+xIhnNCPEJ3Yd/LG72PR5IltPSU1B0+Mb2QJu92A k0HZq+kgsmUZt27CZisRea8zIX+8xr8ajr9Y6oXFDpJA4vUDYIJQpy2M2+Q5fJJUPF AIuVn42BKtAQYRxJLX4dH+izcQA5wkYCkNRBH9qQ= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Florian Weimer To: glibc-cvs@sourceware.org Subject: [glibc/release/2.31/master] stdio: Add tests for printf multibyte convertion leak [BZ#25691] X-Act-Checkin: glibc X-Git-Author: Adhemerval Zanella X-Git-Refname: refs/heads/release/2.31/master X-Git-Oldrev: ae7748e67fb77b6ba8751001718c911d5209400c X-Git-Newrev: 5a802723db55a93fbc9306375da5f40e37d3b3d6 Message-Id: <20220830082330.A4225384D184@sourceware.org> Date: Tue, 30 Aug 2022 08:23:30 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=5a802723db55a93fbc9306375da5f40e37d3b3d6 commit 5a802723db55a93fbc9306375da5f40e37d3b3d6 Author: Adhemerval Zanella Date: Thu Mar 19 18:35:46 2020 -0300 stdio: Add tests for printf multibyte convertion leak [BZ#25691] Checked on x86_64-linux-gnu and i686-linux-gnu. (cherry picked from commit 910a835dc96c1f518ac2a6179fc622ba81ffb159) Diff: --- stdio-common/Makefile | 9 +++- stdio-common/tst-printf-bz25691.c | 108 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 95af0c12d7..0a8d66b846 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -66,6 +66,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ tst-scanf-round \ tst-renameat2 tst-bz11319 tst-bz11319-fortify2 \ scanf14a scanf16a \ + tst-printf-bz25691 test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble @@ -75,10 +76,12 @@ tests-special += $(objpfx)tst-unbputc.out $(objpfx)tst-printf.out \ $(objpfx)tst-printf-bz18872-mem.out \ $(objpfx)tst-setvbuf1-cmp.out \ $(objpfx)tst-vfprintf-width-prec-mem.out \ - $(objpfx)tst-printfsz-islongdouble.out + $(objpfx)tst-printfsz-islongdouble.out \ + $(objpfx)tst-printf-bz25691-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-vfprintf-width-prec.mtrace tst-vfprintf-width-prec-mem.out \ + tst-printf-bz25691.mtrace tst-printf-bz25691-mem.out endif include ../Rules @@ -100,6 +103,8 @@ endif tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace tst-vfprintf-width-prec-ENV = \ MALLOC_TRACE=$(objpfx)tst-vfprintf-width-prec.mtrace +tst-printf-bz25691-ENV = \ + MALLOC_TRACE=$(objpfx)tst-printf-bz25691.mtrace $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' > $@; \ diff --git a/stdio-common/tst-printf-bz25691.c b/stdio-common/tst-printf-bz25691.c new file mode 100644 index 0000000000..37b30a3a8a --- /dev/null +++ b/stdio-common/tst-printf-bz25691.c @@ -0,0 +1,108 @@ +/* Test for memory leak with large width (BZ#25691). + 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 + . */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int +do_test (void) +{ + mtrace (); + + /* For 's' conversion specifier with 'l' modifier the array must be + converted to multibyte characters up to the precision specific + value. */ + { + /* The input size value is to force a heap allocation on temporary + buffer (in the old implementation). */ + const size_t winputsize = 64 * 1024 + 1; + wchar_t *winput = xmalloc (winputsize * sizeof (wchar_t)); + wmemset (winput, L'a', winputsize - 1); + winput[winputsize - 1] = L'\0'; + + char result[9]; + const char expected[] = "aaaaaaaa"; + int ret; + + ret = snprintf (result, sizeof (result), "%.65537ls", winput); + TEST_COMPARE (ret, winputsize - 1); + TEST_COMPARE_BLOB (result, sizeof (result), expected, sizeof (expected)); + + ret = snprintf (result, sizeof (result), "%ls", winput); + TEST_COMPARE (ret, winputsize - 1); + TEST_COMPARE_BLOB (result, sizeof (result), expected, sizeof (expected)); + + free (winput); + } + + /* For 's' converstion specifier the array is interpreted as a multibyte + character sequence and converted to wide characters up to the precision + specific value. */ + { + /* The input size value is to force a heap allocation on temporary + buffer (in the old implementation). */ + const size_t mbssize = 32 * 1024; + char *mbs = xmalloc (mbssize); + memset (mbs, 'a', mbssize - 1); + mbs[mbssize - 1] = '\0'; + + const size_t expectedsize = 32 * 1024; + wchar_t *expected = xmalloc (expectedsize * sizeof (wchar_t)); + wmemset (expected, L'a', expectedsize - 1); + expected[expectedsize-1] = L'\0'; + + const size_t resultsize = mbssize * sizeof (wchar_t); + wchar_t *result = xmalloc (resultsize); + int ret; + + ret = swprintf (result, resultsize, L"%.65537s", mbs); + TEST_COMPARE (ret, mbssize - 1); + TEST_COMPARE_BLOB (result, (ret + 1) * sizeof (wchar_t), + expected, expectedsize * sizeof (wchar_t)); + + ret = swprintf (result, resultsize, L"%1$.65537s", mbs); + TEST_COMPARE (ret, mbssize - 1); + TEST_COMPARE_BLOB (result, (ret + 1) * sizeof (wchar_t), + expected, expectedsize * sizeof (wchar_t)); + + /* Same test, but with an invalid multibyte sequence. */ + mbs[mbssize - 2] = 0xff; + + ret = swprintf (result, resultsize, L"%.65537s", mbs); + TEST_COMPARE (ret, -1); + + ret = swprintf (result, resultsize, L"%1$.65537s", mbs); + TEST_COMPARE (ret, -1); + + free (mbs); + free (result); + free (expected); + } + + return 0; +} + +#include