From patchwork Sat Jul 27 09:13:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 1965630 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; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Y5xLd48F; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; 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 [IPv6:2620:52:3:1:0:246e:9693:128c]) (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 4WWJpw4DQzz1yYc for ; Sat, 27 Jul 2024 19:14:32 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D5C86385828E for ; Sat, 27 Jul 2024 09:14:30 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 64699385842D for ; Sat, 27 Jul 2024 09:14:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 64699385842D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 64699385842D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722071653; cv=none; b=bL3CtsFsVBSxKkrGBFqP2EL1yAHu6lZvcKWjrj+/XubQhRogUddI9m72kCnJetvV1fuK+nXP6BYsiJ8Dxm43DHXr9u5WgFOaicQrvkSErwgqYIOEtqOX6zC3xFaYP0GJ4nHsTmPK1KZgqDCibgD2BYGZOuInX3GpMxOVU5dkAeg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722071653; c=relaxed/simple; bh=IRpJMvLxFAL/c6O4hJqyqxheKtCMx2Pfm185H51y/bY=; h=DKIM-Signature:From:To:Subject:Message-ID:Date:MIME-Version; b=cS95A47AvLGjoyqWiozYJBbceBK4w9NWAIIJziWkTjGPM+t4BUPfDEhET/+3LED/f2879f5Co4AXbcLkZyIQy8TzFoZq6wMyUSaXYvPLZdGLSWL2QZSpx3VbZ2abmRIbw2Ru8FShmgGlE7rRpEZx17m7hE7TjaB2L2tQgrNRDUs= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722071649; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=8ZVQ1QFataemHrAu3thukmr971fGFrBGWc+R9Ppzfpw=; b=Y5xLd48FFHosnwPxf4AwG3J6zM9KRnN62SyMfdZbBE623Hh2otlK7+zhOtTOedO5pBSeT1 Cr2G5kIAfbIZZwRBct4XzCNeZroJEWJ/enL0gIxxRZCUyZ9wfFu7xN/Lm2E1YDVMul0fU7 EvP6BQ1eFVqET2HjqIuncfwyWkW2xro= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-320-s0uLyzv2NX-rRL5IZHnMyQ-1; Sat, 27 Jul 2024 05:14:01 -0400 X-MC-Unique: s0uLyzv2NX-rRL5IZHnMyQ-1 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (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) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 624271955D44 for ; Sat, 27 Jul 2024 09:14:00 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.45.224.36]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 521F81955D42 for ; Sat, 27 Jul 2024 09:13:59 +0000 (UTC) From: Florian Weimer To: libc-alpha@sourceware.org Subject: [PATCH 2/2] string: strerror, strsignal cannot use buffer after dlmopen (bug 32026) In-Reply-To: Message-ID: <2c6783afcba4c3e9046be2908f64180280d1f520.1722071588.git.fweimer@redhat.com> References: X-From-Line: 2c6783afcba4c3e9046be2908f64180280d1f520 Mon Sep 17 00:00:00 2001 Date: Sat, 27 Jul 2024 11:13:56 +0200 User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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~incoming=patchwork.ozlabs.org@sourceware.org Secondary namespaces have a different malloc. Allocating the buffer in one namespace and freeing it another results in heap corruption. Fix this by using a static string (potentially translated) in secondary namespaces. It would also be possible to use the malloc from the initial namespace to manage the buffer, but these functions would still not be safe to use in auditors etc. because a call to strerror could still free a buffer while it is used by the application. Another approach could use proper initial-exec TLS, duplicated in secondary namespaces, but that would need a callback interface for freeing libc resources in namespaces on thread exit, which does not exist today. Tested on x86_64-linux-gnu. Reviewed-by: Adhemerval Zanella --- string/strerror_l.c | 35 ++++++++++++++++++++++++----------- string/strsignal.c | 34 ++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/string/strerror_l.c b/string/strerror_l.c index 15cce261e6..70456e5bb4 100644 --- a/string/strerror_l.c +++ b/string/strerror_l.c @@ -20,7 +20,7 @@ #include #include #include - +#include static const char * translate (const char *str, locale_t loc) @@ -31,6 +31,12 @@ translate (const char *str, locale_t loc) return res; } +static char * +unknown_error (locale_t loc) +{ + return (char *) translate ("Unknown error", loc); +} + /* Return a string describing the errno code in ERRNUM. */ char * @@ -40,18 +46,25 @@ __strerror_l (int errnum, locale_t loc) char *err = (char *) __get_errlist (errnum); if (__glibc_unlikely (err == NULL)) { - struct tls_internal_t *tls_internal = __glibc_tls_internal (); - free (tls_internal->strerror_l_buf); - if (__asprintf (&tls_internal->strerror_l_buf, "%s%d", - translate ("Unknown error ", loc), errnum) > 0) - err = tls_internal->strerror_l_buf; - else + if (__libc_initial) { - /* The memory was freed above. */ - tls_internal->strerror_l_buf = NULL; - /* Provide a fallback translation. */ - err = (char *) translate ("Unknown error", loc); + struct tls_internal_t *tls_internal = __glibc_tls_internal (); + free (tls_internal->strerror_l_buf); + if (__asprintf (&tls_internal->strerror_l_buf, "%s%d", + translate ("Unknown error ", loc), errnum) > 0) + err = tls_internal->strerror_l_buf; + else + { + /* The memory was freed above. */ + tls_internal->strerror_l_buf = NULL; + /* Provide a fallback translation. */ + err = unknown_error (loc); + } } + else + /* Secondary namespaces use a different malloc, so cannot + participate in the buffer management. */ + err = unknown_error (loc); } else err = (char *) translate (err, loc); diff --git a/string/strsignal.c b/string/strsignal.c index 3114601564..808e474e15 100644 --- a/string/strsignal.c +++ b/string/strsignal.c @@ -21,6 +21,7 @@ #include #include #include +#include /* Return a string describing the meaning of the signal number SIGNUM. */ char * @@ -30,21 +31,26 @@ strsignal (int signum) if (desc != NULL) return _(desc); - struct tls_internal_t *tls_internal = __glibc_tls_internal (); - free (tls_internal->strsignal_buf); + if (__libc_initial) + { + struct tls_internal_t *tls_internal = __glibc_tls_internal (); + free (tls_internal->strsignal_buf); - int r; + int r; #ifdef SIGRTMIN - if (signum >= SIGRTMIN && signum <= SIGRTMAX) - r = __asprintf (&tls_internal->strsignal_buf, _("Real-time signal %d"), - signum - SIGRTMIN); - else + if (signum >= SIGRTMIN && signum <= SIGRTMAX) + r = __asprintf (&tls_internal->strsignal_buf, _("Real-time signal %d"), + signum - SIGRTMIN); + else #endif - r = __asprintf (&tls_internal->strsignal_buf, _("Unknown signal %d"), - signum); - - if (r == -1) - tls_internal->strsignal_buf = NULL; - - return tls_internal->strsignal_buf; + r = __asprintf (&tls_internal->strsignal_buf, _("Unknown signal %d"), + signum); + + if (r >= 0) + return tls_internal->strsignal_buf; + } + /* Fall through on asprintf error, and for !__libc_initial: + secondary namespaces use a different malloc and cannot + participate in the buffer management. */ + return _("Unknown signal"); }