From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2178) id CB5AD383E6A2; Mon, 23 May 2022 09:08:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CB5AD383E6A2 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] stdio-common: Add tst-memstream-string for open_memstream overflow X-Act-Checkin: glibc X-Git-Author: Florian Weimer X-Git-Refname: refs/heads/master X-Git-Oldrev: b094c52b1b65693368d0d70c505e0d0b4edad1c2 X-Git-Newrev: 0060a6de5493aeb4af457511e9b9ab532a6930a5 Message-Id: <20220523090835.CB5AD383E6A2@sourceware.org> Date: Mon, 23 May 2022 09:08:35 +0000 (GMT) X-BeenThere: glibc-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 May 2022 09:08:35 -0000 https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=0060a6de5493aeb4af457511e9b9ab532a6930a5 commit 0060a6de5493aeb4af457511e9b9ab532a6930a5 Author: Florian Weimer Date: Mon May 23 10:08:18 2022 +0200 stdio-common: Add tst-memstream-string for open_memstream overflow This code path is exercised indirectly by some of the DNS stub resolver tests, via their own use of xopen_memstream for constructing strings describing result data. The relative lack of test suite coverage became apparent when these tests starting failing after a printf changes uncovered bug 28949. Reviewed-by: Adhemerval Zanella Diff: --- stdio-common/Makefile | 3 ++ stdio-common/tst-memstream-string.c | 77 +++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 2750334714..b1e9144de0 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -175,6 +175,7 @@ tests := \ tst-gets \ tst-grouping \ tst-long-dbl-fphex \ + tst-memstream-string \ tst-obprintf \ tst-perror \ tst-popen \ @@ -390,6 +391,8 @@ CFLAGS-tst-gets.c += -Wno-deprecated-declarations # the fortified version had the same bug. CFLAGS-tst-bz11319-fortify2.c += -D_FORTIFY_SOURCE=2 +CFLAGS-tst-memstream-string.c += -fno-builtin-fprintf + CPPFLAGS += $(libio-mtsafe) $(objpfx)tst-setvbuf1.out: /dev/null $(objpfx)tst-setvbuf1 diff --git a/stdio-common/tst-memstream-string.c b/stdio-common/tst-memstream-string.c new file mode 100644 index 0000000000..0a31e0c12c --- /dev/null +++ b/stdio-common/tst-memstream-string.c @@ -0,0 +1,77 @@ +/* Test writing differently sized strings to a memstream. + Copyright (C) 2022 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 + +/* Returns a printable ASCII character based on INDEX. */ +static inline char +char_from_index (unsigned int index) +{ + return ' ' + (index % 95); +} + +enum { result_size = 25000 }; + +static void +run_one_size (unsigned int chunk_size) +{ + char *chunk = xmalloc (chunk_size + 1); + + struct xmemstream mem; + xopen_memstream (&mem); + unsigned int written = 0; + for (unsigned int i = 0; i < result_size; ) + { + unsigned int to_print = result_size - i; + if (to_print > chunk_size) + to_print = chunk_size; + for (unsigned int j = 0; j < to_print; ++j) + chunk[j] = char_from_index(i + j); + chunk[to_print] = '\0'; + fprintf (mem.out, "%s", chunk); /* Needs -fno-builtin-fprintf. */ + i += to_print; + written += strlen(chunk); + } + xfclose_memstream (&mem); + + TEST_COMPARE (written, result_size); + TEST_COMPARE (mem.length, result_size); + TEST_COMPARE (strlen (mem.buffer), result_size); + + for (unsigned int i = 0; i < result_size; ++i) + TEST_COMPARE (mem.buffer[i], char_from_index (i)); + + free (mem.buffer); + free (chunk); +} + +static int +do_test (void) +{ + for (unsigned int chunk_size = 1; chunk_size <= 30; ++ chunk_size) + run_one_size (chunk_size); + + return 0; +} + +#include