From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id DF7E73857432 for ; Fri, 25 Jun 2021 06:58:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DF7E73857432 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-445-xjzhU-TIPOqTSiHj1xYaaQ-1; Fri, 25 Jun 2021 02:58:55 -0400 X-MC-Unique: xjzhU-TIPOqTSiHj1xYaaQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D0B758015D0; Fri, 25 Jun 2021 06:58:53 +0000 (UTC) Received: from oldenburg.str.redhat.com (ovpn-112-228.ams2.redhat.com [10.36.112.228]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9484619C44; Fri, 25 Jun 2021 06:58:49 +0000 (UTC) From: Florian Weimer To: libc-alpha@sourceware.org Cc: Szabolcs Nagy , Adhemerval Zanella , Carlos O'Donell Subject: [PATCH] elf: Disable most of TLS modid gaps processing [BZ #27135] Date: Fri, 25 Jun 2021 08:58:47 +0200 Message-ID: <8735t6juqg.fsf@oldenburg.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain X-Spam-Status: No, score=-12.7 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_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Jun 2021 06:59:00 -0000 Revert "elf: Fix DTV gap reuse logic [BZ #27135]" This reverts commit 572bd547d57a39b6cf0ea072545dc4048921f4c3. It turns out that the _dl_next_tls_modid in _dl_map_object_from_fd keeps returning the same modid over and over again if there is a gap and more than TLS-using module is loaded in one dlopen call. This corrupts TLS data structures. The bug is still present after a revert, but empirically it is much more difficult to trigger (because it involves a dlopen failure). Tested on i386-linux-gnu and x86_64-linux-gnu. --- elf/dl-close.c | 6 +----- elf/dl-open.c | 10 ++++++++++ elf/dl-tls.c | 5 ++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/elf/dl-close.c b/elf/dl-close.c index 9f31532f41..3720e47dd1 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -88,11 +88,7 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp, /* If this is not the last currently used entry no need to look further. */ if (idx != GL(dl_tls_max_dtv_idx)) - { - /* There is an unused dtv entry in the middle. */ - GL(dl_tls_dtv_gaps) = true; - return true; - } + return true; } while (idx - disp > (disp == 0 ? 1 + GL(dl_tls_static_nelem) : 0)) diff --git a/elf/dl-open.c b/elf/dl-open.c index d2240d8747..a066f39bd0 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -899,6 +899,16 @@ no more namespaces available for dlmopen()")); state if relocation failed, for example. */ if (args.map) { + /* Maybe some of the modules which were loaded use TLS. + Since it will be removed in the following _dl_close call + we have to mark the dtv array as having gaps to fill the + holes. This is a pessimistic assumption which won't hurt + if not true. There is no need to do this when we are + loading the auditing DSOs since TLS has not yet been set + up. */ + if ((mode & __RTLD_AUDIT) == 0) + GL(dl_tls_dtv_gaps) = true; + _dl_close_worker (args.map, true); /* All l_nodelete_pending objects should have been deleted diff --git a/elf/dl-tls.c b/elf/dl-tls.c index e531ec5913..2b5161d10a 100644 --- a/elf/dl-tls.c +++ b/elf/dl-tls.c @@ -191,7 +191,10 @@ _dl_next_tls_modid (void) size_t _dl_count_modids (void) { - /* The count is the max unless dlclose or failed dlopen created gaps. */ + /* It is rare that we have gaps; see elf/dl-open.c (_dl_open) where + we fail to load a module and unload it leaving a gap. If we don't + have gaps then the number of modids is the current maximum so + return that. */ if (__glibc_likely (!GL(dl_tls_dtv_gaps))) return GL(dl_tls_max_dtv_idx);