{"id":2234837,"url":"http://patchwork.ozlabs.org/api/1.2/patches/2234837/?format=json","web_url":"http://patchwork.ozlabs.org/project/glibc/patch/20260508060410.13725-2-gaoxiang@kylinos.cn/","project":{"id":41,"url":"http://patchwork.ozlabs.org/api/1.2/projects/41/?format=json","name":"GNU C Library","link_name":"glibc","list_id":"libc-alpha.sourceware.org","list_email":"libc-alpha@sourceware.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260508060410.13725-2-gaoxiang@kylinos.cn>","list_archive_url":null,"date":"2026-05-08T06:04:09","name":"[v5,1/2] libio: Ignore setbuf for open_memstream and open_wmemstream [BZ #34019]","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"ce3c514ae77c179b01a5c5f1ab6629ea877402cc","submitter":{"id":92909,"url":"http://patchwork.ozlabs.org/api/1.2/people/92909/?format=json","name":"Gao Xiang","email":"gaoxiang@kylinos.cn"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/glibc/patch/20260508060410.13725-2-gaoxiang@kylinos.cn/mbox/","series":[{"id":503327,"url":"http://patchwork.ozlabs.org/api/1.2/series/503327/?format=json","web_url":"http://patchwork.ozlabs.org/project/glibc/list/?series=503327","date":"2026-05-08T06:04:09","name":"libio: Keep memstream result buffers independent of setvbuf","version":5,"mbox":"http://patchwork.ozlabs.org/series/503327/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2234837/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2234837/checks/","tags":{},"related":[],"headers":{"Return-Path":"<libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org>","X-Original-To":["incoming@patchwork.ozlabs.org","libc-alpha@sourceware.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","libc-alpha@sourceware.org"],"Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org\n (client-ip=38.145.34.32; helo=vm01.sourceware.org;\n envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n dmarc=none (p=none dis=none) header.from=kylinos.cn","sourceware.org; spf=pass smtp.mailfrom=kylinos.cn","sourceware.org;\n arc=none smtp.remote-ip=124.126.103.232"],"Received":["from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4gBdv22gr4z1yJq\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 08 May 2026 16:07:26 +1000 (AEST)","from vm01.sourceware.org (localhost [IPv6:::1])\n\tby sourceware.org (Postfix) with ESMTP id CED324BA2E18\n\tfor <incoming@patchwork.ozlabs.org>; Fri,  8 May 2026 06:07:23 +0000 (GMT)","from mailgw.kylinos.cn (mailgw.kylinos.cn [124.126.103.232])\n by sourceware.org (Postfix) with ESMTPS id 14BDB4BA2E07\n for <libc-alpha@sourceware.org>; Fri,  8 May 2026 06:07:00 +0000 (GMT)","from bogon [(117.61.28.11)] by mailgw.kylinos.cn\n (envelope-from <gaoxiang@kylinos.cn>)\n (Generic MTA with TLSv1.3 TLS_AES_256_GCM_SHA384 256/256)\n with ESMTP id 83946949; Fri, 08 May 2026 14:06:51 +0800"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org CED324BA2E18","OpenDKIM Filter v2.11.0 sourceware.org 14BDB4BA2E07"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 14BDB4BA2E07","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 14BDB4BA2E07","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1778220421; cv=none;\n b=u07+4IW17gkN6KFc+xVoCo59wij0XQFXzieDYdb/RTmbhtLFvwJI/4oaIZDi1UEy9gloVDY5gRU6/3+eB2q65s3DqWMjfUkSNowVhpVzvuTF9xolbnk178PSqzD701uT6oP27B0X7Q/9lX7acw2pqN5LzotQGoeFmvLSZOnTlqY=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1778220421; c=relaxed/simple;\n bh=L72UlkFdFpzKFzW/bQSS27evpK/Zzq3B2hF0j3teuWw=;\n h=From:To:Subject:Date:Message-ID:MIME-Version;\n b=RdAiXHEDt2oBtxmSpuNyvHSDWtJVEMaYre2GMruhl+NqV6Q7X3Qva+D2YJicB0EX/y1VgdPPIASas9cAnx6vBsAqYrMN9YBLDsAsDOsyQC0T91rnxhEj9Ct3D67L1cFOVTfh0vqC/rczA5tW1Ze4oPToSJvL1KHRyNTNtc8V4qs=","ARC-Authentication-Results":"i=1; sourceware.org","X-UUID":["1b2d24344aa411f1aa26b74ffac11d73-20260508","1b2d24344aa411f1aa26b74ffac11d73-20260508"],"X-CTIC-Tags":"HR_CC_COUNT, HR_CC_DOMAIN_COUNT, HR_CC_NAME, HR_CTE_8B,\n HR_CTT_MISS\n HR_DATE_H, HR_DATE_WKD, HR_DATE_ZONE, HR_FROM_NAME, HR_SJ_DIGIT_LEN\n HR_SJ_LANG, HR_SJ_LEN, HR_SJ_LETTER, HR_SJ_NOR_SYM, HR_SJ_PHRASE\n HR_SJ_PHRASE_LEN, HR_SJ_WS, HR_TO_COUNT, HR_TO_DOMAIN_COUNT, HR_TO_NO_NAME\n IP_UNTRUSTED, SRC_UNTRUSTED, IP_UNFAMILIAR, SRC_UNFAMILIAR, DN_TRUSTED\n SRC_TRUSTED, SA_EXISTED, SN_TRUSTED, SN_EXISTED, SPF_NOPASS\n DKIM_NOPASS, DMARC_NOPASS, UD_TRUSTED, CIE_GOOD_SPF, CIE_UNKNOWN\n GTI_FG_BS, GTI_C_CI, GTI_FG_IT, GTI_RG_INFO, GTI_C_BU\n AMN_T1, AMN_GOOD, AMN_C_TI, ABX_MISS_RDNS","X-CID-O-RULE":"Release_Ham","X-CID-RULE":"Release_Ham","X-CID-O-INFO":"VERSION:1.3.12, REQID:6190ae81-f923-46f8-9ef7-8e84b86f7121,\n IP:10,\n URL:0,TC:0,Content:0,EDM:0,RT:0,SF:-5,FILE:0,BULK:0,RULE:Release_Ham,ACTIO\n N:release,TS:5","X-CID-INFO":"VERSION:1.3.12, REQID:6190ae81-f923-46f8-9ef7-8e84b86f7121, IP:10,\n UR\n L:0,TC:0,Content:0,EDM:0,RT:0,SF:-5,FILE:0,BULK:0,RULE:Release_Ham,ACTION:\n release,TS:5","X-CID-META":"VersionHash:e7bac3a, CLOUDID:56a17f5cbe08e900575b5f4e51d40635,\n BulkI\n D:260508140652J5GO6CFM,BulkQuantity:0,Recheck:0,SF:17|19|66|78|81|82|102|1\n 27|898,TC:nil,Content:0|15|50,EDM:-3,IP:-2,URL:1,File:nil,RT:nil,Bulk:nil,\n QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0\n ,ARC:0","X-CID-BVR":"2,SSN|SDN","X-CID-BAS":"2,SSN|SDN,0,_","X-CID-FACTOR":"TF_CID_SPAM_FSD,TF_CID_SPAM_ULS,TF_CID_SPAM_SNR,TF_CID_SPAM_FAS","X-CID-RHF":"D41D8CD98F00B204E9800998ECF8427E","X-User":"gaoxiang@kylinos.cn","From":"Gao Xiang <gaoxiang@kylinos.cn>","To":"libc-alpha@sourceware.org","Cc":"Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>,\n Andreas Schwab <schwab@suse.de>, Rocket Ma <marocketbd@gmail.com>,\n Xiang Gao <gaoxiang@kylinos.cn>","Subject":"[PATCH v5 1/2] libio: Ignore setbuf for open_memstream and\n open_wmemstream [BZ #34019]","Date":"Fri,  8 May 2026 14:04:09 +0800","Message-ID":"<20260508060410.13725-2-gaoxiang@kylinos.cn>","X-Mailer":"git-send-email 2.53.0","In-Reply-To":"<20260508060410.13725-1-gaoxiang@kylinos.cn>","References":"<20260507094000.22966-1-gaoxiang@kylinos.cn>\n <20260508060410.13725-1-gaoxiang@kylinos.cn>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-BeenThere":"libc-alpha@sourceware.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Libc-alpha mailing list <libc-alpha.sourceware.org>","List-Unsubscribe":"<https://sourceware.org/mailman/options/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=unsubscribe>","List-Archive":"<https://sourceware.org/pipermail/libc-alpha/>","List-Post":"<mailto:libc-alpha@sourceware.org>","List-Help":"<mailto:libc-alpha-request@sourceware.org?subject=help>","List-Subscribe":"<https://sourceware.org/mailman/listinfo/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=subscribe>","Errors-To":"libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org"},"content":"From: Xiang Gao <gaoxiang@kylinos.cn>\n\nopen_memstream and open_wmemstream manage an internal growable buffer.\nThe default setbuf hook can reset that buffer, breaking the assumptions\nused by the string stream overflow paths.\n\nInstall setbuf hooks that leave the internal buffer unchanged, and add\nregression test cases for the narrow and wide cases, based on the\nreproducer in BZ #34019.\n\nChecked on x86_64 with no regression in the libio tests.\n\nReported-by: Rocket Ma <marocketbd@gmail.com>\nSigned-off-by: Xiang Gao <gaoxiang@kylinos.cn>\n---\n libio/Makefile                |  2 ++\n libio/libioP.h                |  4 ++++\n libio/memstream.c             |  8 +++++++\n libio/tst-memstream-setbuf.c  | 41 +++++++++++++++++++++++++++++++++++\n libio/tst-wmemstream-setbuf.c | 20 +++++++++++++++++\n libio/vtables.c               |  6 +++--\n libio/wmemstream.c            |  8 +++++++\n 7 files changed, 87 insertions(+), 2 deletions(-)\n create mode 100644 libio/tst-memstream-setbuf.c\n create mode 100644 libio/tst-wmemstream-setbuf.c","diff":"diff --git a/libio/Makefile b/libio/Makefile\nindex 93656466df..6b56567d44 100644\n--- a/libio/Makefile\n+++ b/libio/Makefile\n@@ -116,6 +116,7 @@ tests = \\\n   tst-ftell-partial-wide \\\n   tst-fwrite-error \\\n   tst-getdelim \\\n+  tst-memstream-setbuf \\\n   tst-memstream1 \\\n   tst-memstream2 \\\n   tst-memstream3 \\\n@@ -139,6 +140,7 @@ tests = \\\n   tst-wfile-sync \\\n   tst-wfiledoallocate-static \\\n   tst-widetext \\\n+  tst-wmemstream-setbuf \\\n   tst-wmemstream1 \\\n   tst-wmemstream2 \\\n   tst-wmemstream3 \\\ndiff --git a/libio/libioP.h b/libio/libioP.h\nindex 1485d22619..fa44ad0e57 100644\n--- a/libio/libioP.h\n+++ b/libio/libioP.h\n@@ -740,8 +740,12 @@ extern size_t __IO_obstack_xsputn (FILE *fp, const void *data, size_t n)\n /* Jumptable functions for open_{w}memstream.  */\n extern int _IO_mem_sync (FILE* fp) __THROW attribute_hidden;\n extern void _IO_mem_finish (FILE* fp, int) __THROW attribute_hidden;\n+extern FILE *_IO_mem_setbuf (FILE *fp, char *buf, ssize_t size)\n+  __THROW attribute_hidden;\n extern int _IO_wmem_sync (FILE* fp) __THROW attribute_hidden;\n extern void _IO_wmem_finish (FILE* fp, int) __THROW attribute_hidden;\n+extern FILE *_IO_wmem_setbuf (FILE *fp, char *buf, ssize_t size)\n+  __THROW attribute_hidden;\n \n /* Other strfile functions */\n struct _IO_strfile_;\ndiff --git a/libio/memstream.c b/libio/memstream.c\nindex 0456adb92f..69b400d928 100644\n--- a/libio/memstream.c\n+++ b/libio/memstream.c\n@@ -112,3 +112,11 @@ _IO_mem_finish (FILE *fp, int dummy)\n \n   _IO_str_finish (fp, 0);\n }\n+\n+\n+FILE *\n+_IO_mem_setbuf (FILE *fp, char *p, ssize_t len)\n+{\n+  /* Memstream manage a growable buffer internally.  */\n+  return fp;\n+}\ndiff --git a/libio/tst-memstream-setbuf.c b/libio/tst-memstream-setbuf.c\nnew file mode 100644\nindex 0000000000..eee176ede5\n--- /dev/null\n+++ b/libio/tst-memstream-setbuf.c\n@@ -0,0 +1,41 @@\n+/* Test for open_memstream BZ #34019.\n+   Copyright (C) 2026 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <https://www.gnu.org/licenses/>.  */\n+\n+#include <libio/tst-memstream.h>\n+\n+static int\n+do_test (void)\n+{\n+  /* setbuf must not replace the internal growable buffer.  */\n+  CHAR_T *buf = NULL;\n+  size_t len = 0;\n+  FILE *fp = OPEN_MEMSTREAM (&buf, &len);\n+  setbuf (fp, NULL);\n+  TEST_COMPARE (FPUTC (W('A'), fp), W('A'));\n+  TEST_COMPARE (fclose (fp), 0);\n+  TEST_COMPARE (len, 1);\n+  TEST_VERIFY_EXIT (buf != NULL);\n+  TEST_VERIFY (buf[0] == W('A'));\n+  TEST_VERIFY (buf[1] == W('\\0'));\n+\n+  free (buf);\n+\n+  return 0;\n+}\n+\n+#include <support/test-driver.c>\ndiff --git a/libio/tst-wmemstream-setbuf.c b/libio/tst-wmemstream-setbuf.c\nnew file mode 100644\nindex 0000000000..6ce751708a\n--- /dev/null\n+++ b/libio/tst-wmemstream-setbuf.c\n@@ -0,0 +1,20 @@\n+/* Test for open_wmemstream BZ #34019.\n+   Copyright (C) 2026 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <https://www.gnu.org/licenses/>.  */\n+\n+#define TEST_WCHAR\n+#include <libio/tst-memstream-setbuf.c>\ndiff --git a/libio/vtables.c b/libio/vtables.c\nindex 00d9d25b5e..ca9f1b2dc4 100644\n--- a/libio/vtables.c\n+++ b/libio/vtables.c\n@@ -77,9 +77,11 @@\n # pragma weak _IO_cookie_write\n \n # pragma weak _IO_mem_finish\n+# pragma weak _IO_mem_setbuf\n # pragma weak _IO_mem_sync\n \n # pragma weak _IO_wmem_finish\n+# pragma weak _IO_wmem_setbuf\n # pragma weak _IO_wmem_sync\n \n # pragma weak __printf_buffer_as_file_overflow\n@@ -334,7 +336,7 @@ const struct _IO_jump_t __io_vtables[] attribute_relro =\n     JUMP_INIT (xsgetn, _IO_default_xsgetn),\n     JUMP_INIT (seekoff, _IO_str_seekoff),\n     JUMP_INIT (seekpos, _IO_default_seekpos),\n-    JUMP_INIT (setbuf, _IO_default_setbuf),\n+    JUMP_INIT (setbuf, _IO_mem_setbuf),\n     JUMP_INIT (sync, _IO_mem_sync),\n     JUMP_INIT (doallocate, _IO_default_doallocate),\n     JUMP_INIT (read, _IO_default_read),\n@@ -357,7 +359,7 @@ const struct _IO_jump_t __io_vtables[] attribute_relro =\n     JUMP_INIT (xsgetn, _IO_wdefault_xsgetn),\n     JUMP_INIT (seekoff, _IO_wstr_seekoff),\n     JUMP_INIT (seekpos, _IO_default_seekpos),\n-    JUMP_INIT (setbuf, _IO_default_setbuf),\n+    JUMP_INIT (setbuf, _IO_wmem_setbuf),\n     JUMP_INIT (sync, _IO_wmem_sync),\n     JUMP_INIT (doallocate, _IO_wdefault_doallocate),\n     JUMP_INIT (read, _IO_default_read),\ndiff --git a/libio/wmemstream.c b/libio/wmemstream.c\nindex d0c639be70..cdee2a4151 100644\n--- a/libio/wmemstream.c\n+++ b/libio/wmemstream.c\n@@ -117,3 +117,11 @@ _IO_wmem_finish (FILE *fp, int dummy)\n \n   _IO_wstr_finish (fp, 0);\n }\n+\n+\n+FILE *\n+_IO_wmem_setbuf (FILE *fp, char *p, ssize_t len)\n+{\n+  /* Wmemstreams manage a growable buffer internally.  */\n+  return fp;\n+}\n","prefixes":["v5","1/2"]}