From patchwork Tue Dec 15 18:44:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 41415 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 23CAC38708C8; Tue, 15 Dec 2020 18:45:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 23CAC38708C8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1608057917; bh=9sLLCEutTvj/LpNOZMGDFnb6gaegZG0AZGtqDe48W9E=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=vUFoFXI7oalBk+5vvrEesqaZ1NfSDTtEFX/k6VpSccXIghC23T53gyp4Is6YoKV8H /JYGullqfzFbLvSlN/fjvaMVkfO9EXGrzqCUCH2ZCJdOtHJ0RVrMd9pbCXUZsqaNZP bgmDKF0aKrTw5zeP6LDiPasgFFjwcTcMbVbqwta0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by sourceware.org (Postfix) with ESMTPS id AB3D23851C26 for ; Tue, 15 Dec 2020 18:45:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org AB3D23851C26 Received: from noise.cbg.collabora.co.uk (unknown [IPv6:2001:4d48:ad5c:ef00:8e70:5aff:fe59:c29c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: vivek) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 5994F1F45614 for ; Tue, 15 Dec 2020 18:45:08 +0000 (GMT) To: libc-alpha Subject: [RFC][PATCH v6 05/20] elf/dl-fini.c: Handle proxy link_map entries in the shutdown path Date: Tue, 15 Dec 2020 18:44:45 +0000 Message-Id: <20201215184500.25915-6-vivek@collabora.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201215184500.25915-1-vivek@collabora.com> References: <20201215184500.25915-1-vivek@collabora.com> MIME-Version: 1.0 X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_PASS, 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-Patchwork-Original-From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra_via_Libc-alpha?= From: Vivek Dasmohapatra Reply-To: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" 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 8e146ecee1..4847b3294f 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -283,8 +283,9 @@ _dl_close_worker (struct link_map *map, bool force) /* Call its termination function. Do not do it for half-cooked objects. Temporarily disable exception - handling, so that errors are fatal. */ - if (imap->l_init_called) + handling, so that errors are fatal. + 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, @@ -360,7 +361,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. */ @@ -686,8 +689,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 @@ -727,19 +732,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 231db3d66d..25feb5216d 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -73,7 +73,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); @@ -111,7 +111,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;