From patchwork Thu Apr 2 17:23:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rocket Ma X-Patchwork-Id: 132635 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 260364BA23E3 for ; Thu, 2 Apr 2026 17:25:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 260364BA23E3 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=f1qF7UTH X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-dy1-x1335.google.com (mail-dy1-x1335.google.com [IPv6:2607:f8b0:4864:20::1335]) by sourceware.org (Postfix) with ESMTPS id 430334BA5436 for ; Thu, 2 Apr 2026 17:24:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 430334BA5436 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 430334BA5436 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1335 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775150671; cv=none; b=JvCYEKCZKvjCHAXE51yRxRWhc+aeQuOS82bpWg66G52TacN5IaN70P9jCHyu3dkz948fsAOSrU4U1OYTxid4aw+8FduqFMN2h9gjABQBGcQJ/WbzDQf8o+cnOPsN15LonpD2cNNnlpECD48H+4nSnLty1SXKyQp2fg4OfmnNm4M= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775150671; c=relaxed/simple; bh=dnHrQXmMP4gterSL8u8n/fGLoZYzJMb/Hxmym8YSf/A=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=pXgZI8iBwrfhaulluinH701hvOY+3/+ROOSum6BaiqpXWfSRBCrQB25RU5XSG5SF0Df9rfyqLqNlnqacHxxuI0YTopktwmIcZ5suJIeYvDZVz8y7JX3LvWDVOGqqNDaKgtwWeK8On7rDVRgY9QB815S6RCuYVOZsF0VxNQ5qqoU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 430334BA5436 Received: by mail-dy1-x1335.google.com with SMTP id 5a478bee46e88-2cbdd9852aaso165739eec.0 for ; Thu, 02 Apr 2026 10:24:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775150670; x=1775755470; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=P3Q51d1rn8JgUwy1GVZD9k5QZvUN8sb8wXFZ9UWsOgY=; b=f1qF7UTHR1YO1zS9nB21zeKiSMs6jII4YPwtwBpgG43ElQjzYJkTxKex4LlnANbvs9 Hy+E9JhQPLyqteVm7EwC5z5ifF7Z05aUOfS2gzATXBw6lzeLm1yrt3hfwx7M2BmJoXD/ 2FWtAjH7iO7v4BYbZiOb1jU6Cw8B+PxmQ3k7waJIQ/929ciWtZYPephiY8OxrquuRsxR jrLvaqo2Y1O6uG1Dxaf4RoOtPqhdnUcfUOiO2DIyK9VebWFBF34D2Fs4yvQS0xxa41ru EuK2o2c3iCwythBStA3+EcV2U11UTend2qmW9M9RPPnpK4QwSJ2vYqWYCTXVpExsV5te MaXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775150670; x=1775755470; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=P3Q51d1rn8JgUwy1GVZD9k5QZvUN8sb8wXFZ9UWsOgY=; b=TJtKtbIC/89ViYqEZoRcy+o8Fyg3C1sVqRbqaIxM7OuQB9TILZrCYK9AZ7g4+8FywZ PwG6gfwOPqA0avwYfvkxwtHe5GbQTegiHf9CVlLLR/b5HQx2tBiWMtYwuVQUbKS7neWc OqC4NgQqi4utrN1CKdslJJlDvS3sFDIW+MYjBPmIsyskDu/o3Fg6dfZvC7lRWgROkBgp WJu1mw8U/ZaXZEK/Y5FKwnwmP/lH9lOsaq/QfVYQa6Dxm7wuR8uGMhTdTZe9oOf2Ygzs D7koq+jTdWM7+QjCvDXyypj85htn3eGoWsEdK2W0nxwSFjyXu4sp/Ku2ET2eoMWaRM/u QGbg== X-Gm-Message-State: AOJu0YwJe9N+qPjJ902KcN6UK2Wazt9sIaYcFifarGS8IgQPayFSosKG bH1dk2WxqVX7yloxbqZVVw10F6lO+C2JvBmcht/DmUK78cg5f9ekKB7QvuBFJuDy X-Gm-Gg: AeBDievrHJ15uotFEI76/kFA8nDGoUeG8vvhedQ6y9Z8WMxnB5ZoRZeblL/DmBK5lCX w/utUPPOsE4fhWLkdt2EpwPE6z3iGuUPDZFwSwrIiZ3oyOIAjdir3XUDHxnkJ7HC9XMnwdM86py Cv+EmC9qhoC0X/QfoEpldAwCSiwXXNHMbIc1ejjukoTMekNBU8jDinmb3I3mVTVl7/kd340AlWV b/oTGEVp0xdVbHgsYbzFvz64bjFzzAsdp90y8zSpgFuXPTn2w6pGs3eVbV3M7NgVp0fNSWS/96k XKcPzzadCI9chokSoomnOcw45UMDpodpPcRdNW8Pb6WEMw1pqRy66oyjhkjzAUEq01scI5UehUS 1ghtIwN5x3AU7ft0pWkj4RSsun8EBGkdwuooGyM6YS38aKQyzhzUcHR9ykfUsEAZlL8+/z6goRw L0kvjemOarwGYdw2XO3xStrAVkPD7wuiSTcIoT4uAFNaeF6gEv8cQdvYIInEMrjO8hK+ZR/P1U7 A0qSuoO X-Received: by 2002:a05:7301:6085:b0:2c0:c415:cfd6 with SMTP id 5a478bee46e88-2ca8d9c7814mr2148014eec.13.1775150670086; Thu, 02 Apr 2026 10:24:30 -0700 (PDT) Received: from localhost ([23.94.240.252]) by smtp.gmail.com with UTF8SMTPSA id 5a478bee46e88-2ca7c20c151sm3176455eec.19.2026.04.02.10.24.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Apr 2026 10:24:29 -0700 (PDT) From: Rocket Ma To: Adhemerval Zanella Netto Cc: libc-alpha@sourceware.org Subject: [PATCH v3] stdio-common: Fix heap overflow in scanf %mc pattern [BZ #34008] Date: Thu, 2 Apr 2026 10:23:36 -0700 Message-ID: <20260402172336.253214-1-marocketbd@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP 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 * stdio-common/vfscanf-internal.c: when `WIDTH` in `%WIDTHmc` or `%WIDTHmC` greater than 1024, user could read one more byte into heap, leading into off-by-one overflow. This patch fixes Bug 34008[1]. [1]: https://sourceware.org/bugzilla/show_bug.cgi?id=34008 Use support/check.h for regression test Signed-off-by: Rocket Ma --- stdio-common/Makefile | 1 + stdio-common/bug-vfscanf-internal.c | 59 +++++++++++++++++++++++++++++ stdio-common/vfscanf-internal.c | 6 +-- 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 stdio-common/bug-vfscanf-internal.c diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 210944837e..ec3fff246b 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -200,6 +200,7 @@ aux := \ tests := \ bug-vfprintf-nargs \ + bug-vfscanf-internal \ bug1 \ bug3 \ bug4 \ diff --git a/stdio-common/bug-vfscanf-internal.c b/stdio-common/bug-vfscanf-internal.c new file mode 100644 index 0000000000..54ab192e50 --- /dev/null +++ b/stdio-common/bug-vfscanf-internal.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include +#include + +static size_t +get_cookie (size_t *chunk) +{ +/* heap related test need to ignore out-of-bound access */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" + return chunk[-1] & ~1; /* ignore prev_inuse bit */ +#pragma GCC diagnostic pop +} + +#if __SIZEOF_POINTER__ == 8 +# define WIDTH 0x409 +# define SCANFSTR "%1033mc" +#else /* 32bit target? */ +# define WIDTH 0x40d +# define SCANFSTR "%1037mc" +#endif +#define CHUNKSZ 0x410 +static int +do_test (void) +{ + char *input = malloc (WIDTH + 1); + TEST_VERIFY (input != NULL); + memset (input, 'A', WIDTH); + input[WIDTH] = '\0'; + + /* THIS TEST UNIT REQUIRE SOME HEAP LAYOUT! Which is related to + current ptmalloc, when malloc is updated, this test may be inaccurate. + Anyway, we should construct a case where we allocate a chunk just + lower than scanf-alloced chunk to detect if heap overflow happens. */ + void *hole = malloc (WIDTH - 1); + size_t *guard = malloc (0x20); + if ((size_t) hole + CHUNKSZ != (size_t) guard) + { + puts ("Unexpected heap layout: \"guard\" is not adjacent to \"hole\""); + return 77; + } + size_t cookie = get_cookie (guard); + free (hole); + + char *buf = NULL; + TEST_VERIFY (sscanf (input, SCANFSTR, &buf) != -1); + TEST_VERIFY (buf != NULL); + TEST_VERIFY (get_cookie (guard) == cookie); + + free (buf); + free (input); + return 0; +} + +#include diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c index 59fc8208aa..b33ee0652c 100644 --- a/stdio-common/vfscanf-internal.c +++ b/stdio-common/vfscanf-internal.c @@ -856,7 +856,7 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, /* Enlarge the buffer. */ size_t newsize = strsize - + (strsize >= width ? width - 1 : strsize); + + (strsize >= width ? width : strsize); str = (char *) realloc (*strptr, newsize); if (str == NULL) @@ -929,7 +929,7 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, && wstr == (wchar_t *) *strptr + strsize) { size_t newsize - = strsize + (strsize > width ? width - 1 : strsize); + = strsize + (strsize > width ? width : strsize); /* Enlarge the buffer. */ wstr = (wchar_t *) realloc (*strptr, newsize * sizeof (wchar_t)); @@ -984,7 +984,7 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, && wstr == (wchar_t *) *strptr + strsize) { size_t newsize - = strsize + (strsize > width ? width - 1 : strsize); + = strsize + (strsize > width ? width : strsize); /* Enlarge the buffer. */ wstr = (wchar_t *) realloc (*strptr, newsize * sizeof (wchar_t));