From patchwork Tue Jun 24 16:32:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 115001 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 B2DD238560AB for ; Tue, 24 Jun 2025 16:34:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B2DD238560AB Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=jCc6Rpqe X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by sourceware.org (Postfix) with ESMTPS id C418E3857C5D for ; Tue, 24 Jun 2025 16:33:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C418E3857C5D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C418E3857C5D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::52d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1750782811; cv=none; b=urj66Q8D/brfR5MInMmtY/9+Udep+6VBtLNGznOmwBqdd1dUAS0cpkMxk4FIcxBjfsNP9f1Hmd4q8uu1E4HYn4nbnszUUWU0GYU9vDxFmn2FOU99iQrLBZS3m7UHPSxWJ1jojLAa5fldT6Ts28+IEGVxobWA2iy83+UXG4eiPoQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1750782811; c=relaxed/simple; bh=pxwqM0MAzebiPQX16d0/vRXXKbip6mE9HiaZhyIJOvA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=A5/Ui7L9/RFBMMkKf2i3sY6bpNZQlPXW1Bih6zZMf7J3NDE1MXQb+rtfnqWzPi1uxloqJMe/jPrdZi6RtodLRoRhFw1UOc4tSwAZCn+35CbodmX1tAcsO0phFCHjnRC1bC1hr7E1YmknrIeAr3JYltdVUl29rygd0lx+ZbbYE2g= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C418E3857C5D Received: by mail-pg1-x52d.google.com with SMTP id 41be03b00d2f7-b34a6d0c9a3so998191a12.3 for ; Tue, 24 Jun 2025 09:33:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1750782809; x=1751387609; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=dDzyKdytQUHN5kxiLuRRtWxiblW0G5y5nZ2gWaBP+50=; b=jCc6RpqeO/EbuWMIt/eJg0rzlSaXdyKo6Hlt8cCV1ng4JrezeqWUU8SqRbYiBCCska CsEwRnBIOGgILAZrMQQINCP9vZa4sTOERn5o4AClKFgvYDpn4qr0vp3Eh229CCujCrSd Ph2HimmyvWjEy0NZusWyfRnle5JsZaI0MhFnTNowyrzOC4tKzQZwBA9Hbnw2RXTTPDTA osQBX1DvF8+R8RGxBRZtOPlOYCNx66gYLHooG81Bm0E2z/o24zv8mWLOb+a8MYuzr8M1 e9xWdRXIH04KDous4Ix0Z9MakU2AbPSdLmIsbp8oy+H4BI4XzlE96jmgPJbHMZ79yxYV 05Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750782809; x=1751387609; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=dDzyKdytQUHN5kxiLuRRtWxiblW0G5y5nZ2gWaBP+50=; b=TDj4abceeVtNSHUj9eIEeWA4svo0AyEKQg6U4I5h2kEj0+GLmBQu1HxXPIERZ1NOEP WEc7tq9z1tnKjjcUboM2Xzu41URNghqLltDgErTAYFXl7n0jXxZOrCw9CT2NagcmXWm+ /Qzszoz0fwwnOCEvBXCA1918EcRAW5G6hiKgi+cEoJpteZWXFbdEeTPA+kBjCKSn1icN Cmrf6U8rHYOQcYO1sZrYcGTyNmZyoT1WDiDC3CYllfQ4Tgc2xzaWUI0nn6r4JOUkR7rn fkmQKwdk3XTGGJOV/1iDJTX/TEktA+UKyt0c6VMTzNvmYpsUwKmEhzmUBFaSlXEMkEfY rzJQ== X-Gm-Message-State: AOJu0Yw1RcJv1JCr1qpZ8U0K2CuM1PKOdDXoasQnBxRXKPSRFsP7sEOU 1lNNmz/+miOHOQpx5oVXTdm+egWPFexawio0FRJirWH9mznYionBS7b1BgnO1b+74cBrOU9uoyi Yrd8n X-Gm-Gg: ASbGncvKFJCiwhtEn5r3ACHxAbCkedkdvWKCh4jHl2rt8em9r7AbYon+N/0v6N/xE4x bvh/9RVWHt5IiyzxaMhk8XuTTg2CozuyLLTT6mFps5j8k0TLUGK4qZq0l3JCQKrsyA35gsYgynM n98Cz7plQAfp2pXxb10gkA8JIEr+dJ9iB6B4LHf0X+wdZ83QTe+vf0ZsnjAjBIzwXIQkCbwTS/H 0BHVvF9G+U5Cndl8OzzD74XTumGbd5okv02BafFKyy7xNUWZ+9vMfq+MF5CCjcm2slNRH84nqSZ oGgOAJ4s94bq2VJ+jzx7bhg/qDowNbLpSrvGFXw8qvHkP9gf9ErMBhJlS+o9JiuEC/IM/5a/9fc = X-Google-Smtp-Source: AGHT+IHXhp3NpHJXtyiY1WQUv9MGsn516NHYR9Mfn5LGF9njfFPSKMGKzA3krmUkcegSOv48XKjADQ== X-Received: by 2002:a05:6a00:2d1b:b0:748:33f3:8da8 with SMTP id d2e1a72fcca58-7490d663646mr21582712b3a.5.1750782809394; Tue, 24 Jun 2025 09:33:29 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c3:d288:ce0e:42bf:aaa5:7d70]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-749c882cec9sm2259602b3a.75.2025.06.24.09.33.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Jun 2025 09:33:28 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Carlos O'Donell Subject: [PATCH v3] stdlib: Fix __libc_message_impl iovec size (BZ 32947) Date: Tue, 24 Jun 2025 13:32:08 -0300 Message-ID: <20250624163323.816694-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, 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 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~patchwork=sourceware.org@sourceware.org The iovec size should account for all substrings between each conversion specification. For the format: "abc %s efg" The list of substrings are: ["abc ", arg, " efg] which is 2 times the number of maximum arguments *plus* one. This issue triggered 'out of bounds' errors by stdlib/tst-bz20544 when glibc is built with experimental UBSAN support [1]. Besides adjusting the iovec size, a new runtime and check is added to avoid wrong __libc_message_impl usage. Checked on x86_64-linux-gnu. [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/ubsan-undef Co-authored-by: Carlos O'Donell --- Changes from v2: * Add runtime check and regression testcase. Changes from v1: * Add bug report. --- include/stdio.h | 4 ++++ posix/Makefile | 2 ++ posix/tst-libc-message.c | 48 ++++++++++++++++++++++++++++++++++++++ sysdeps/posix/libc_fatal.c | 36 +++++++++++++++------------- 4 files changed, 74 insertions(+), 16 deletions(-) create mode 100644 posix/tst-libc-message.c diff --git a/include/stdio.h b/include/stdio.h index e48d709919..3d917dba5b 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -173,6 +173,10 @@ libc_hidden_proto (__fortify_fail) /* The maximum number of varargs allowed in a __libc_message format string */ #define LIBC_MESSAGE_MAX_ARGS 4 +#define IOVEC_MAX_ERR_MSG "Fatal glibc error: Internal " \ + "__libc_message error. Too many arguments.\n" +#define IOVEC_MAX_ERR_MSG_LEN (sizeof (IOVEC_MAX_ERR_MSG) - 1) + _Noreturn void __libc_message_impl (const char *__fnt, ...) attribute_hidden __attribute__ ((__format__ (__printf__, 1, 2))); diff --git a/posix/Makefile b/posix/Makefile index c0e224236a..6986aef948 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -348,6 +348,7 @@ tests-internal := \ bug-regex5 \ bug-regex20 \ bug-regex33 \ + tst-libc-message \ # tests-internal tests-container := \ @@ -392,6 +393,7 @@ endif tests-static = \ tst-exec-static \ tst-spawn-static \ + tst-libc-message \ # tests-static tests += \ diff --git a/posix/tst-libc-message.c b/posix/tst-libc-message.c new file mode 100644 index 0000000000..b85195e338 --- /dev/null +++ b/posix/tst-libc-message.c @@ -0,0 +1,48 @@ +/* Internal test to verify __libc_fatal. + Copyright (C) 2025 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 + +static _Noreturn void +run_libc_message (void *closure) +{ + /* We only support 4 arguments. Call with 5 to trigger failure. */ + __libc_message_impl ("%s %s %s %s %s\n", "1", "2", "3", "4", "5"); + __builtin_unreachable (); +} + +static int +do_test (void) +{ + struct support_capture_subprocess result + = support_capture_subprocess (run_libc_message, NULL); + support_capture_subprocess_check (&result, "libc_message", -SIGABRT, + sc_allow_stderr); + + TEST_COMPARE_STRING (result.err.buffer, IOVEC_MAX_ERR_MSG); + + support_capture_subprocess_free (&result); + + return 0; +} + +#include diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c index d90cc6c681..6f75197e96 100644 --- a/sysdeps/posix/libc_fatal.c +++ b/sysdeps/posix/libc_fatal.c @@ -16,23 +16,13 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include #ifdef FATAL_PREPARE_INCLUDE #include FATAL_PREPARE_INCLUDE @@ -47,6 +37,10 @@ writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total) } #endif +/* At most a substring before each conversion specification and the + trailing substring (the plus one). */ +#define IOVEC_MAX (LIBC_MESSAGE_MAX_ARGS * 2 + 1) + /* Abort with an error message. */ void __libc_message_impl (const char *fmt, ...) @@ -61,7 +55,7 @@ __libc_message_impl (const char *fmt, ...) if (fd == -1) fd = STDERR_FILENO; - struct iovec iov[LIBC_MESSAGE_MAX_ARGS * 2 - 1]; + struct iovec iov[IOVEC_MAX]; int iovcnt = 0; ssize_t total = 0; @@ -99,6 +93,16 @@ __libc_message_impl (const char *fmt, ...) iov[iovcnt].iov_len = len; total += len; iovcnt++; + + if (__glibc_unlikely (iovcnt > IOVEC_MAX)) + { + len = IOVEC_MAX_ERR_MSG_LEN; + iov[0].iov_base = (char *) IOVEC_MAX_ERR_MSG; + iov[0].iov_len = len; + total = len; + iovcnt = 1; + break; + } } va_end (ap);