From patchwork Wed Sep 2 08:19:53 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?7IaQ64+Z6regL1Byb2Nlc3MgJiBJbmZyYSBMYWIoU1IpL+yCvOyEseyghOyekA==?= X-Patchwork-Id: 142681 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2A07F4BA7980 for ; Wed, 2 Sep 2026 08:20:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2A07F4BA7980 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=samsung.com header.i=@samsung.com header.a=rsa-sha256 header.s=mail20170921 header.b=sdDgbb9p X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) by sourceware.org (Postfix) with ESMTPS id 34C934BA2E24 for ; Wed, 2 Sep 2026 08:19:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 34C934BA2E24 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=samsung.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 34C934BA2E24 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=203.254.224.25 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788337199; cv=none; b=ng3wxUHcu3dJJcfyxrgjohvxrB5kUWt4Kzqc04bw8yjsf5mFU/wuVvdRfe0Ra04xamaUdoPHk99hqPJWUTA0xhB8XFjRkuNanIAFYE6HbvaHAH3rwsTS8PCvquQfGW57S73XhHPJRsuPqK8IUx1vtjsBpOUxf/1yx4MHifuNyc0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788337199; c=relaxed/simple; bh=JLSycZnqawY5vh5guVuN92T09rAbMQZlMXzMPr2L/7U=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=PFgIqJwSfTMGy2N1RoJzBhwxd/f4SbGXf3rP4Z37v+oQyeuMixIPOOUwaA1zLE4GWAtl7dc5aMDC0ZhfvSGhr+NehcgH2Zt+Yr06DKouhsllXUNUoMwnuT7QkHRAa3+KNgozVDnp1sEUDh//P9SOGaA9hm+nhVIXj7lWjtDVd4g= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=samsung.com header.i=@samsung.com header.a=rsa-sha256 header.s=mail20170921 header.b=sdDgbb9p DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 34C934BA2E24 Received: from epcas1p3.samsung.com (unknown [182.195.41.47]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20260902081955epoutp0201a9ed39a86f641d605823f8032b4032~RczRP4msI2505925059epoutp02m for ; Wed, 2 Sep 2026 08:19:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20260902081955epoutp0201a9ed39a86f641d605823f8032b4032~RczRP4msI2505925059epoutp02m DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1788337195; bh=f1k2Ae9BvvFSYrOwrmvYS93WwnCqYSi83rAhVjC8GMk=; h=From:To:Cc:Subject:Date:References:From; b=sdDgbb9p2ovpxoRItJpQ8kwZUtwoX/p11JsKNs3mllorg0c/efmA64f6FLMH2YZDL z/olj+jL3PbhatNgcro0qphEkCSmnkHgVYlyLi3Onx/WD6ZL/zUaeYNJsyq4l+8wOU NVn4KFqLhp1pZ1dGG83d1i0oftrX5UGZVHvUg+xE= Received: from epsnrtp02.localdomain (unknown [182.195.42.154]) by epcas1p1.samsung.com (KnoxPortal) with ESMTPS id 20260902081955epcas1p1f169a2c91677c1c1a95022fb5af73321~RczQ8YiAA2135721357epcas1p1Q; Wed, 2 Sep 2026 08:19:55 +0000 (GMT) Received: from epcas1p2.samsung.com (unknown [182.195.38.98]) by epsnrtp02.localdomain (Postfix) with ESMTP id 4hZbHt4Ynhz2SSKd; Wed, 2 Sep 2026 08:19:54 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas1p2.samsung.com (KnoxPortal) with ESMTPA id 20260902081954epcas1p20ac45f8fcaa7a3ea51dbdf5c6fb1334e~RczP5xuQ80400904009epcas1p2M; Wed, 2 Sep 2026 08:19:54 +0000 (GMT) Received: from dongkyuns002 (unknown [10.113.112.105]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260902081954epsmtip1881728792c0aa64c4d23dc14376ecbc7~RczP2oZLF3106931069epsmtip1C; Wed, 2 Sep 2026 08:19:54 +0000 (GMT) From: =?ks_c_5601-1987?b?vNW1v7HVL1Byb2Nlc3MgJiBJbmZyYSBMYWIoU1IpL7vvvLo=?= =?ks_c_5601-1987?b?wPzA2g==?= To: Cc: "'Florian Weimer'" , =?ks_c_5601-1987?b?J7OqvLqxuSc=?= Subject: [PATCH v4] libio: Fix CVE-2026-18374 heap buffer overflow in ccs= handling Date: Wed, 2 Sep 2026 17:19:53 +0900 Message-ID: <012e01dd3ab3$d50da0a0$7f28e1e0$@samsung.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: Ad06s6+cmMyYZ9a7RWW8wImHyr6T8A== Content-Language: ko x-msg-type: PERSONAL x-drm-type: PERSONAL X-CMS-MailID: 20260902081954epcas1p20ac45f8fcaa7a3ea51dbdf5c6fb1334e X-Msg-Generator: CA CMS-TYPE: 101P cpgsPolicy: CPGSC10-361,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20260902081954epcas1p20ac45f8fcaa7a3ea51dbdf5c6fb1334e References: X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, CHARSET_FARAWAY_HEADER, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_NONE, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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~patchwork=sourceware.org@sourceware.org When fopen() is called with a ,ccs= parameter whose value becomes empty after strip(), the code must reject it with EINVAL instead of attempting to use it. The original upstr() fallback could read past the ',' delimiter and cause a heap buffer overflow. The fix checks if the charset specification is empty after strip() and returns EINVAL immediately, preventing the overflow and following the approach described in BZ #34574. A regression test is added using /dev/null with both trivially empty (,ccs=) and effectively-empty-after-strip (,ccs=/) cases, verifying that EINVAL is returned. CVE-2026-18374 - CVSS 4.9 (AV:L/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L) Reported-by: AISLE in partnership with Red Hat Signed-off-by: Dongkyun Son --- libio/fileops.c | 14 ++++++++++++-- libio/tst-fopenloc.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/libio/fileops.c b/libio/fileops.c index 9348d7c3a1..80ea5e90ad 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -355,8 +355,18 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode, *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0'; strip (ccs, ccs); - if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0' - ? upstr (ccs, cs + 5) : ccs) != 0) + /* After stripping, ccs[2] == '\0' means the charset name is empty. + This is not a valid charset and would cause problems downstream. + Reject it with EINVAL (BZ #34574, CVE-2026-18374). */ + if (ccs[2] == '\0') + { + (void) _IO_file_close_it (fp); + free (ccs); + __set_errno (EINVAL); + return NULL; + } + + if (__wcsmbs_named_conv (&fcts, ccs) != 0) { /* Something went wrong, we cannot load the conversion modules. This means we cannot proceed since the user explicitly asked diff --git a/libio/tst-fopenloc.c b/libio/tst-fopenloc.c index ea3f7b5265..78d3819817 100644 --- a/libio/tst-fopenloc.c +++ b/libio/tst-fopenloc.c @@ -85,6 +85,44 @@ do_bz18906 (void) return EXIT_SUCCESS; } +static int +do_cve_2026_18374 (void) +{ + /* CVE-2026-18374 (BZ #34574): Test that fopen() rejects an effectively + empty ccs= specification. The ,ccs= parameter that is not empty before + strip() but becomes empty after strip() should fail with EINVAL. */ + + FILE *fp = fopen ("/dev/null", "r,ccs=/"); + if (fp != NULL) + { + printf ("fopen with empty-after-strip ccs= should have failed\n"); + fclose (fp); + return 1; + } + if (errno != EINVAL) + { + printf ("expected EINVAL, got %d\n", errno); + return 1; + } + + /* Also check the trivially empty ,ccs= case. */ + errno = 0; + fp = fopen ("/dev/null", "r,ccs="); + if (fp != NULL) + { + printf ("fopen with empty ccs= should have failed\n"); + fclose (fp); + return 1; + } + if (errno != EINVAL) + { + printf ("expected EINVAL, got %d\n", errno); + return 1; + } + + return 0; +} + static int do_test (void) { @@ -110,6 +148,7 @@ do_test (void) TEST_COMPARE (do_bz17916 (), 0); TEST_COMPARE (do_bz18906 (), 0); + TEST_COMPARE (do_cve_2026_18374 (), 0); return EXIT_SUCCESS; }