From patchwork Thu Mar 17 19:29:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 52069 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 874EE386EC15 for ; Thu, 17 Mar 2022 19:35:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 874EE386EC15 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1647545727; bh=R1E+sglm3kC8J0MzF1l317Nr4S4g8NOXrPFKMerWJaE=; h=To:Subject:In-Reply-To:References:Date:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=BXCVtTFK2Kp9vQLVXUonLi3HRRTqfX2pYZPtJ6w88xGwByw0iOXLScObuvZFkmRn8 244FlTQXRedr/iZvbvd/0J5dYHUTkEJu1s7WN0QhpS04fpJYjYQusH8f/nuO2J+IZu Yu/PjCxhppxR488SLYLrNwxoX/2n4GDKDGwN4xFY= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id F1325385ED4A for ; Thu, 17 Mar 2022 19:29:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F1325385ED4A Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-631-_rXGyk_WM1OXtgzHA8q-jw-1; Thu, 17 Mar 2022 15:29:38 -0400 X-MC-Unique: _rXGyk_WM1OXtgzHA8q-jw-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 028843C02184 for ; Thu, 17 Mar 2022 19:29:38 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.192.88]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 617A640147D for ; Thu, 17 Mar 2022 19:29:37 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH 08/26] stdio-common: Add tst-memstream-string for open_memstream overflow In-Reply-To: References: X-From-Line: 2d35bb583d26a0dce2d905c2cc79fb87a8e9413b Mon Sep 17 00:00:00 2001 Message-Id: <2d35bb583d26a0dce2d905c2cc79fb87a8e9413b.1647544751.git.fweimer@redhat.com> Date: Thu, 17 Mar 2022 20:29:35 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Florian Weimer via Libc-alpha From: Florian Weimer Reply-To: Florian Weimer Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" 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 --- stdio-common/Makefile | 1 + stdio-common/tst-memstream-string.c | 85 +++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 stdio-common/tst-memstream-string.c diff --git a/stdio-common/Makefile b/stdio-common/Makefile index f0e65f0dcd..222c9ea63d 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -173,6 +173,7 @@ tests := \ tst-gets \ tst-grouping \ tst-long-dbl-fphex \ + tst-memstream-string \ tst-obprintf \ tst-perror \ tst-popen \ diff --git a/stdio-common/tst-memstream-string.c b/stdio-common/tst-memstream-string.c new file mode 100644 index 0000000000..1c1bf0154a --- /dev/null +++ b/stdio-common/tst-memstream-string.c @@ -0,0 +1,85 @@ +/* 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); +} + +/* Hide fprintf behind a compiler barrier, to avoid the fputs + transformation. */ +void __attribute__ ((weak)) +fprintf_compiler_barrier (FILE *fp, const char *format, const char *arg) +{ + fprintf (fp, format, arg); +} + +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_compiler_barrier (mem.out, "%s", chunk); + 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