From patchwork Wed Aug 14 23:32:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 1972620 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=aedukWH3; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wkl1b4HmNz1yXZ for ; Thu, 15 Aug 2024 09:33:23 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C8B293858424 for ; Wed, 14 Aug 2024 23:33:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C8B293858424 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1723678401; bh=NslUCYr9Fcu5LyO98ansPTVI5zix8Nh61LZFribpSrA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=aedukWH3NFdTnXR/HVLEoFCS+GCPzBOJY5ovnjMF9QLkeJu++lgryYzZi5ODmpXLx kRj1kyuO40nem7xR3qd3HuaxSSpj+wNHQdd2Ke6Yz/xx1/eka5MoCIrhgYdXNxiNrI HmwAPR81xv6acfRCH46RLNQtJBT8xSb5FBbAYXKs= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from fossa.ash.relay.mailchannels.net (fossa.ash.relay.mailchannels.net [23.83.222.62]) by sourceware.org (Postfix) with ESMTPS id 796443858404 for ; Wed, 14 Aug 2024 23:32:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 796443858404 Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=sourceware.org Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=sourceware.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 796443858404 Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=23.83.222.62 ARC-Seal: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1723678363; cv=pass; b=OwUTOBZXI5dSJpmKT+vHVceORTYRKs3HUgisK1eHftmhEc1Saj/rCln6KoZyZy+Ap5KE1SlCLMZJqmG8WkX/5yBA/j1tRB1lKeJRd9/ZeNCcKHDq74XL6VzS1me6scpN3qyt6hklEN4d3XacmHvYvjsVCuS9kXLXgfwjcSWvgkg= ARC-Message-Signature: i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1723678363; c=relaxed/simple; bh=gRLArS50VyIJwJBZqjJkbhlusBuk5/SBj5JIB4fJBVQ=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=gmpXKM/W3vk6uMIx2Rs+JjoTGQ605XtIjzXi8PPzbyG315pGLVzU4OLAoGtMlpXab+KsQCwtjTIjUn2by9f1xU8IyQ9iYzbD7EXoVWn1X3pOxsGnq1DULzjFA0neg3t+AmNRJNJl93UorWJ2eCVaDIJQT1GyqzYZLCfoJGJ4rk0= ARC-Authentication-Results: i=2; server2.sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 1D2BC547A01; Wed, 14 Aug 2024 23:32:39 +0000 (UTC) Received: from pdx1-sub0-mail-a310.dreamhost.com (unknown [127.0.0.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id C087D547980; Wed, 14 Aug 2024 23:32:38 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1723678358; a=rsa-sha256; cv=none; b=t2TU9HgRSNXkjsSRUpZ8XWZ5w1Bp9su3igqrh5ulOpIeFNuK1Ufdsf/kXLFafWaSpbVSh+ lTDrjuhl3HLCV8QsTTfuWxsCHCBtJzj2HwvOUJlZg5MmKUcNLYqsvfEty+UDbZ7YmaLzlA 6BYJOaBj2tKb55SHO8EC0z+rcJuGDsxahUwnzvLsdvzCS3nzLP5Ugd7gENaDG3bprUXSAF q8KiwKWtI8vZHX5gyvSCM8Mn3F8ND5Yi6HHDgh1ho93ALXv4lzTyAJda3YKMkry2P3z+9q 40wsqO/jef8k5/GrGA21GVncH7iEaEZjp7bcKno6Ash2omrjptElcB0jJ4YhJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1723678358; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NslUCYr9Fcu5LyO98ansPTVI5zix8Nh61LZFribpSrA=; b=vlahtX7JRFuDIvXUr0+X0hKUucRqtBNc6DbRSykA6hwXVS2OYYRcDtwwd9tcNji86qESuB YbWMODsb0dFwyg/v9T0UpEeKif4HcrtQBPNux0kyZrqGEbxhqcxAq9ol4tCuWSBUziysaR leWppTJw4Iv4RD8jkCjtxajOkOekPV+ySazdXDRtX3g4AKPmxr51t6RwcrXNPxqkEXipgi nmvAZKNf8PsKHMnsmhhAgUShr6uicTTzzyH8S6Kleqpk2tg5+3K1QYi9tiNwlin1vBiEks QCqhwvuKiDms81mKm0DHAZSbFEP44mBIXkCLMZfyH1yhAt3GiyGVk7gia6hugA== ARC-Authentication-Results: i=1; rspamd-587694846-hkz9k; auth=pass smtp.auth=dreamhost smtp.mailfrom=siddhesh@sourceware.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Quick-Desert: 1113eb6013c7678a_1723678359014_3511709817 X-MC-Loop-Signature: 1723678359013:1117967267 X-MC-Ingress-Time: 1723678359013 Received: from pdx1-sub0-mail-a310.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.117.75.39 (trex/7.0.2); Wed, 14 Aug 2024 23:32:39 +0000 Received: from fedora.redhat.com (bras-base-toroon4859w-grc-84-184-146-171-51.dsl.bell.ca [184.146.171.51]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a310.dreamhost.com (Postfix) with ESMTPSA id 4Wkl0k3CH8zTh; Wed, 14 Aug 2024 16:32:38 -0700 (PDT) From: Siddhesh Poyarekar To: libc-alpha@sourceware.org Cc: fweimer@redhat.com Subject: [PATCH 2/2] ungetc: Fix backup buffer leak on program exit [BZ #27821] Date: Wed, 14 Aug 2024 19:32:32 -0400 Message-ID: <20240814233232.1468890-3-siddhesh@sourceware.org> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240814233232.1468890-1-siddhesh@sourceware.org> References: <20240814233232.1468890-1-siddhesh@sourceware.org> MIME-Version: 1.0 X-Spam-Status: No, score=-1171.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org If a file descriptor is left unclosed and is cleaned up by _IO_cleanup on exit, its backup buffer remains unfreed, registering as a leak in valgrind. This is not strictly an issue since (1) the program should ideally be closing the stream once it's not in use and (2) the program is about to exit anyway, so keeping the backup buffer around a wee bit longer isn't a real problem. Free it anyway to keep valgrind happy when the streams in question are the standard ones, i.e. stdout, stdin or stderr. Also, the _IO_have_backup macro checks for _IO_save_base, which is a roundabout way to check for a backup buffer instead of directly looking for _IO_backup_base. The roundabout check breaks when the main get area has not been used and user pushes a char into the backup buffer with ungetc. Fix this to use the _IO_backup_base directly. Signed-off-by: Siddhesh Poyarekar --- libio/genops.c | 6 ++++++ libio/libioP.h | 4 ++-- stdio-common/Makefile | 7 +++++++ stdio-common/tst-ungetc-leak.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 stdio-common/tst-ungetc-leak.c diff --git a/libio/genops.c b/libio/genops.c index b012fa33d2..6ea95c5e68 100644 --- a/libio/genops.c +++ b/libio/genops.c @@ -816,6 +816,12 @@ _IO_unbuffer_all (void) legacy = 1; #endif + /* Free up the backup area if it ever was ever allocated. */ + if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); + if (fp->_mode > 0 && _IO_have_wbackup (fp)) + _IO_free_wbackup_area (fp); + if (! (fp->_flags & _IO_UNBUFFERED) /* Iff stream is un-orientated, it wasn't used. */ && (legacy || fp->_mode != 0)) diff --git a/libio/libioP.h b/libio/libioP.h index 1af287b19f..616253fcd0 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -577,8 +577,8 @@ extern void _IO_old_init (FILE *fp, int flags) __THROW; ((__fp)->_wide_data->_IO_write_base \ = (__fp)->_wide_data->_IO_write_ptr = __p, \ (__fp)->_wide_data->_IO_write_end = (__ep)) -#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL) -#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL) +#define _IO_have_backup(fp) ((fp)->_IO_backup_base != NULL) +#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_backup_base != NULL) #define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP) #define _IO_have_markers(fp) ((fp)->_markers != NULL) #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base) diff --git a/stdio-common/Makefile b/stdio-common/Makefile index e4f0146d2c..a91754f52d 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -254,6 +254,7 @@ tests := \ tst-swscanf \ tst-tmpnam \ tst-ungetc \ + tst-ungetc-leak \ tst-unlockedio \ tst-vfprintf-mbs-prec \ tst-vfprintf-user-type \ @@ -316,6 +317,7 @@ tests-special += \ $(objpfx)tst-printf-bz25691-mem.out \ $(objpfx)tst-printf-fp-free-mem.out \ $(objpfx)tst-printf-fp-leak-mem.out \ + $(objpfx)tst-ungetc-leak-mem.out \ $(objpfx)tst-vfprintf-width-prec-mem.out \ # tests-special @@ -330,6 +332,8 @@ generated += \ tst-printf-fp-leak-mem.out \ tst-printf-fp-leak.mtrace \ tst-scanf-bz27650.mtrace \ + tst-ungetc-leak-mem.out \ + tst-ungetc-leak.mtrace \ tst-vfprintf-width-prec-mem.out \ tst-vfprintf-width-prec.mtrace \ # generated @@ -424,6 +428,9 @@ tst-printf-fp-leak-ENV = \ tst-scanf-bz27650-ENV = \ MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so +tst-ungetc-leak-ENV = \ + MALLOC_TRACE=$(objpfx)tst-ungetc-leak.mtrace \ + LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ diff --git a/stdio-common/tst-ungetc-leak.c b/stdio-common/tst-ungetc-leak.c new file mode 100644 index 0000000000..6c5152b43f --- /dev/null +++ b/stdio-common/tst-ungetc-leak.c @@ -0,0 +1,32 @@ +/* Test for memory leak with ungetc when stream is unused. + Copyright The GNU Toolchain Authors. + 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 + +static int +do_test (void) +{ + mtrace (); + TEST_COMPARE (ungetc('y', stdin), 'y'); + return 0; +} + +#include