From patchwork Wed Jun 6 18:19:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 925998 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-92949-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=collabora.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="pM98zVwU"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 411H6R6D3kz9s01 for ; Thu, 7 Jun 2018 04:20:47 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=atHmkOZHnErXd2KD/uxmdPT2d6Ekbij Vlp0qIZlMIvl2r3yrIVN4mtbLT5CsCe4Su/ve6bT2Ioq0KZ6gqhlmfWluOLTFWyW F6ocN8agePv8WwP166QWm/ku32p4mXsgeIyY+6pPOQzTVGnULEFVR5xBYedMKCG0 mg7Pw5v6XeDA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=RzmhI7SPpaGPh87uOIp/ddAxU/s=; b=pM98z VwUAjOIVLfWYKLelP7I0s11YR+05u78zwmG4bkIuthkuvpv8tUU3hDKVraTV9nHg hH3nn8osB1Uz9iQz7WjShLbaifPLRoOWSV7GFgSG/DmyXYjZbSDIZBypsT/fiBxF V+wT44MH4yzJJerBh4VsyDZPefODBQbIycaVrA= Received: (qmail 22654 invoked by alias); 6 Jun 2018 18:19:52 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 22502 invoked by uid 89); 6 Jun 2018 18:19:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=lnp, H*r:902, Finally, destroying X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Subject: [RFC][PATCH v2 5/6] elf/dl-fini.c: Handle proxy link_map entries in the shutdown path Date: Wed, 6 Jun 2018 18:19:33 +0000 Message-Id: <20180606181934.2480-6-vivek@collabora.com> In-Reply-To: <20180606181934.2480-1-vivek@collabora.com> References: <20180606181934.2480-1-vivek@collabora.com> When cleaning up before exit we should not call destructors or otherwise free [most of] the contents of proxied link_map entries since they share [most of] their contents with the LM_ID_BASE objects to which they point. --- elf/dl-close.c | 43 ++++++++++++++++++++++++++----------------- elf/dl-fini.c | 6 ++++-- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/elf/dl-close.c b/elf/dl-close.c index ecd6729704..6c706a4ae8 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -267,8 +267,9 @@ _dl_close_worker (struct link_map *map, bool force) && (imap->l_flags_1 & DF_1_NODELETE) == 0); /* Call its termination function. Do not do it for - half-cooked objects. */ - if (imap->l_init_called) + half-cooked objects. + Proxies should never have this flag set, but we double check. */ + if (imap->l_init_called && !imap->l_proxy) { /* When debugging print a message first. */ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, @@ -353,7 +354,9 @@ _dl_close_worker (struct link_map *map, bool force) one for the terminating NULL pointer. */ size_t remain = (new_list != NULL) + 1; bool removed_any = false; - for (size_t cnt = 0; imap->l_scope[cnt] != NULL; ++cnt) + for (size_t cnt = 0; + imap->l_scope && imap->l_scope[cnt] != NULL; + ++cnt) /* This relies on l_scope[] entries being always set either to its own l_symbolic_searchlist address, or some map's l_searchlist address. */ @@ -676,8 +679,10 @@ _dl_close_worker (struct link_map *map, bool force) /* We can unmap all the maps at once. We determined the start address and length when we loaded the object and - the `munmap' call does the rest. */ - DL_UNMAP (imap); + the `munmap' call does the rest. Proxies do not have + any segments of their own to unmap. */ + if (!imap->l_proxy) + DL_UNMAP (imap); /* Finally, unlink the data structure and free it. */ #if DL_NNS == 1 @@ -717,19 +722,23 @@ _dl_close_worker (struct link_map *map, bool force) _dl_debug_printf ("\nfile=%s [%lu]; destroying link map\n", imap->l_name, imap->l_ns); - /* This name always is allocated. */ - free (imap->l_name); - /* Remove the list with all the names of the shared object. */ + /* Skip structures borrowed by proxies from the real map. */ + if (!imap->l_proxy) + { + /* This name always is allocated. */ + free (imap->l_name); + /* Remove the list with all the names of the shared object. */ - struct libname_list *lnp = imap->l_libname; - do - { - struct libname_list *this = lnp; - lnp = lnp->next; - if (!this->dont_free) - free (this); - } - while (lnp != NULL); + struct libname_list *lnp = imap->l_libname; + do + { + struct libname_list *this = lnp; + lnp = lnp->next; + if (!this->dont_free) + free (this); + } + while (lnp != NULL); + } /* Remove the searchlists. */ free (imap->l_initfini); diff --git a/elf/dl-fini.c b/elf/dl-fini.c index 3cfc262400..0403f6c4d8 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -72,7 +72,7 @@ _dl_fini (void) assert (nloaded != 0 || GL(dl_ns)[ns]._ns_loaded == NULL); for (l = GL(dl_ns)[ns]._ns_loaded, i = 0; l != NULL; l = l->l_next) /* Do not handle ld.so in secondary namespaces. */ - if (l == l->l_real) + if (l == l->l_real || l->l_proxy) { assert (i < nloaded); @@ -110,7 +110,9 @@ _dl_fini (void) { struct link_map *l = maps[i]; - if (l->l_init_called) + /* Do not call fini functions via proxies, or for + objects which are not marked as initialised. */ + if (l->l_init_called && !l->l_proxy) { /* Make sure nothing happens if we are called twice. */ l->l_init_called = 0;