From patchwork Mon Aug 20 13:54:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 959721 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-95388-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="trP0CbRl"; 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 41vFgV6zkJz9s8T for ; Mon, 20 Aug 2018 23:55:18 +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:in-reply-to:references; q=dns; s=default; b=WTIVVu0Q EdIFLgOiZgfY7dXOm3tZzpIE4YqSbT/XdoxJwW5h1Xy1v3A63s1Ty4VC5B6qC+oA sL60mP4Hf6iDTV8HdHz78bZa4WAEhEFEFZuJ3kSjGTDD6Je3URm/oLyjsXiNtvcI ZehfBRGUN4N9czIAJV3sf5bGAd8yCj4ikh4= 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:in-reply-to:references; s=default; bh=SDlQd5kpnXc5Wg XHlVxy9tLSDFA=; b=trP0CbRlF0hS8GiDR7860oV/6UUPly8f7ZwNbGX4BzktF+ VKV+FHTXk5aV0JmX4gLyfeSKTKixLLz+HQc7XuNOmp+uLOyUQeGh7miunE5e7ne3 N5nJ75peqoxj+M24+u9WvsOlzTjNLqjHBnlNdh88leZWIcX/awREAmRYdMFXI= Received: (qmail 43812 invoked by alias); 20 Aug 2018 13:54:47 -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 43565 invoked by uid 89); 20 Aug 2018 13:54:45 -0000 Authentication-Results: sourceware.org; auth=none 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=demands, instruct X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Subject: [RFC][PATCH v3 1/6] Declare and describe the dlmopen RTLD_SHARED flag Date: Mon, 20 Aug 2018 14:54:26 +0100 Message-Id: <24c5e4682e7ec4292a26eddb9af055acd361995c.1534532485.git.vivek@collabora.com> In-Reply-To: References: In-Reply-To: References: This flag will instruct dlmopen to create a shared object present in the main namespace and accessible from the selected namespace when supplied in the MODE argument. --- bits/dlfcn.h | 7 +++++++ sysdeps/mips/bits/dlfcn.h | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/bits/dlfcn.h b/bits/dlfcn.h index b0b129b66b..52ce898343 100644 --- a/bits/dlfcn.h +++ b/bits/dlfcn.h @@ -32,6 +32,13 @@ visible as if the object were linked directly into the program. */ #define RTLD_GLOBAL 0x00100 +/* If the following bit is set in the MODE argument to dlmopen + then the target object is loaded into the main namespace (if + it is not already there) and a shallow copy (proxy) is placed + in the target namespace: This allows multiple namespaces to + share a single instance of a DSO. */ +#define RTLD_SHARED 0x00080 + /* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL. The implementation does this by default and so we can define the value to zero. */ diff --git a/sysdeps/mips/bits/dlfcn.h b/sysdeps/mips/bits/dlfcn.h index 471ab4fdda..32744ef196 100644 --- a/sysdeps/mips/bits/dlfcn.h +++ b/sysdeps/mips/bits/dlfcn.h @@ -32,6 +32,13 @@ visible as if the object were linked directly into the program. */ #define RTLD_GLOBAL 0x0004 +/* If the following bit is set in the MODE argument to dlmopen + then the target object is loaded into the main namespace (if + it is not already there) and a shallow copy (proxy) is placed + in the target namespace: This allows multiple namespaces to + share a single instance of a DSO. */ +#define RTLD_SHARED 0x00020 + /* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL. The implementation does this by default and so we can define the value to zero. */ From patchwork Mon Aug 20 13:54:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 959717 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-95385-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="FzepWgK2"; 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 41vFg05LkSz9s5c for ; Mon, 20 Aug 2018 23:54:52 +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:in-reply-to:references; q=dns; s=default; b=ujixCYzv zFXuy00QIYCWg/q9hNPgczOoqRpTnBQippOQZkZ+2JSgShzRmdqS+ICUeVib0DpB VXPuK5wgj2N2sCuplYDCFCdoVPp2CO7kcUhB+yGujvHQmznN4UsUsrNT1f3nyC4X rvtYvEwizmXIFV4eWjkn2k2kI7XhUzFpgNw= 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:in-reply-to:references; s=default; bh=VRiar3NQV3C4I4 ZYjtQ09ibubDU=; b=FzepWgK2yIWjfUEnle8i1WaySBjQYzawnoD5WiEsUlFGkI etOlp73d8hbqO2v8/VVwhWHYuygEAg7b9qgR3ktAZQTwFEaINPghr1luR8dqYUyM iVUSmDw1AwE+af6aLTeUsHYAunyqZZipGYlushuEz0nSLeIm4J0N4OqRd2fV0= Received: (qmail 43596 invoked by alias); 20 Aug 2018 13:54:46 -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 43563 invoked by uid 89); 20 Aug 2018 13:54:45 -0000 Authentication-Results: sourceware.org; auth=none 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=reserved X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Subject: [RFC][PATCH v3 2/6] include/link.h: Update the link_map struct to allow proxies Date: Mon, 20 Aug 2018 14:54:27 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: We already have an l_real pointer, used for a similar purpose by the linker for copies of ld.so in secondary namespaces. Update its documentation and add a bitfield to indicate when link_map entry is a proxy. --- include/link.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/link.h b/include/link.h index 5924594548..c07eb35237 100644 --- a/include/link.h +++ b/include/link.h @@ -104,8 +104,9 @@ struct link_map They may change without notice. */ /* This is an element which is only ever different from a pointer to - the very same copy of this type for ld.so when it is used in more - than one namespace. */ + the very same copy of this type when: + - A shallow copy of ld.so is placed in namespaces other than LM_ID_BASE. + - An object is proxied into a namespace by dlmopen with RTLD_SHARED. */ struct link_map *l_real; /* Number of the namespace this link map belongs to. */ @@ -177,6 +178,7 @@ struct link_map unsigned int l_relocated:1; /* Nonzero if object's relocations done. */ unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */ + unsigned int l_proxy:1; /* Nonzero if object is a shallow copy. */ unsigned int l_reserved:2; /* Reserved for internal use. */ unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed to by `l_phdr' is allocated. */ From patchwork Mon Aug 20 13:54:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 959719 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-95387-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="W+UOFv+k"; 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 41vFgL1W7zz9s5c for ; Mon, 20 Aug 2018 23:55:10 +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:in-reply-to:references; q=dns; s=default; b=gud/h7ig 1mamz1p3BEXa+fEx+sLhQKrQG3RM5geb1By4WfPmc8//LLjK45MhZsHMXVv7+tED bMTi45pB4yTuWgrmmv5ZvjqwR0AV68vl2/WbhFCIlZ82NlxSAVSQRuvM1D8kaMJ0 0kGH3uNfzJPQZg533rx+lswMEQuXdaLgJMI= 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:in-reply-to:references; s=default; bh=BfVXChFGCIj6Yd GEJdF5jHy+SQI=; b=W+UOFv+kIQzbc/cC5q0tc6fvS+rNPvoxczvhdjvkuY5bZR B9bDRDJZ6OtP5p2UueRME+UzKNwmQtQvpomowFQSXYKdPuNynQAQV2gPBX+eVkZk duX8ILQZkQIqU1fhk0rM3kroLvXGDA7Z9svTtg8awGzI+eMMcgufvTOOuO98E= Received: (qmail 43708 invoked by alias); 20 Aug 2018 13:54:47 -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 43574 invoked by uid 89); 20 Aug 2018 13:54:46 -0000 Authentication-Results: sourceware.org; auth=none 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=pin, na, *new, accounting X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Subject: [RFC][PATCH v3 3/6] elf/dl-object.c: Implement a helper function to proxy link_map entries Date: Mon, 20 Aug 2018 14:54:28 +0100 Message-Id: <7c351d489f72caf3163ec831aede99dfcadb6c22.1534532485.git.vivek@collabora.com> In-Reply-To: References: In-Reply-To: References: Provides the minimal functionality needed to take an existing link_map entry and create a proxy for it in the specified namespace. --- elf/dl-object.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++ sysdeps/generic/ldsodefs.h | 5 +++ 2 files changed, 90 insertions(+) diff --git a/elf/dl-object.c b/elf/dl-object.c index b37bcc1295..534d7db57a 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -50,6 +51,90 @@ _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid) __rtld_lock_unlock_recursive (GL(dl_load_write_lock)); } +/* Proxy an existing link map entry into a new link map: + This is based on _dl_new_object, skipping the steps we know we won't need + because this is mostly just a shell for the l_real pointer holding the real + link map entry (normally l == l->l_real, but not for ld.so in non-main + link maps or RTLD_SHARED proxies). + It also flags the proxy by setting l_proxy, and sets the the no-delete + flag in the original if it is an lt_loaded. */ +struct link_map * +_dl_new_proxy (struct link_map *old, int mode, Lmid_t nsid) +{ + const char *name; + struct link_map *new; + struct libname_list *newname; +#ifdef SHARED + /* See _dl_new_object for how/why this number is arrived at: */ + unsigned int na = GLRO(dl_naudit); + + if (!na && (mode & __RTLD_OPENEXEC)) + na = DL_NNS; + + size_t audit_space = na * sizeof (new->l_audit[0]); +#else +# define audit_space 0 +#endif + + name = old->l_name; + + /* Find the original link map entry if `old' is itself a proxy. */ + while (old && old->l_proxy) + old = old->l_real; + + if (old == NULL) + _dl_signal_error (EINVAL, name, NULL, N_("cannot proxy NULL link_map")); + + /* Object already exists in the target namespace. This should get handled + by dl_open_worker but just in case we get this far, handle it: */ + if (__glibc_unlikely (old->l_ns == nsid)) + { + /* Not actually possible, given the sanity checks above. */ + if (old->l_proxy) + return old; + + _dl_signal_error (EEXIST, name, NULL, + N_("object cannot be demoted to a proxy")); + } + + /* Now duplicate as little of _dl_new_object as possible to get a + working proxied object in the target link map. */ + new = (struct link_map *) calloc (sizeof (*new) + audit_space + + sizeof (struct link_map *) + + sizeof (*newname) + PATH_MAX, 1); + + if (new == NULL) + _dl_signal_error (ENOMEM, name, NULL, + N_("cannot create shared object descriptor")); + + /* Specific to the proxy. */ + new->l_real = old; + new->l_proxy = 1; + new->l_ns = nsid; + + /* Copied from the origin. */ + new->l_libname = old->l_libname; + new->l_name = old->l_name; + /* Proxies are considered lt_loaded if the real entry type is lt_library. */ + new->l_type = (old->l_type == lt_library) ? lt_loaded : old->l_type; + + if (__glibc_unlikely (mode & RTLD_NODELETE)) + new->l_flags_1 |= DF_1_NODELETE; + + /* Specific to the origin. Ideally we'd do some accounting here but + for now it's easier to pin the original so the proxy remains valid. */ + if (old->l_type == lt_loaded) + old->l_flags_1 |= DF_1_NODELETE; + + /* Fix up the searchlist so that relocations work. */ + _dl_map_object_deps (new, NULL, 0, 0, + mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT)); + + /* And finally put the proxy in the target namespace. */ + _dl_add_to_namespace_list (new, nsid); + + return new; +} /* Allocate a `struct link_map' for a new object being loaded, and enter it into the _dl_loaded list. */ diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 95dc87519b..260926d01a 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -918,6 +918,11 @@ extern lookup_t _dl_lookup_symbol_x (const char *undef, struct link_map *skip_map) attribute_hidden; +/* Proxy an existing link map entry into a new link map */ +extern struct link_map *_dl_new_proxy (struct link_map *old, + int mode, + Lmid_t nsid) + attribute_hidden; /* Add the new link_map NEW to the end of the namespace list. */ extern void _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid) From patchwork Mon Aug 20 13:54:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 959727 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-95391-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="mw7+fohB"; 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 41vFpX3Vqpz9s5c for ; Tue, 21 Aug 2018 00:01:24 +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:mime-version:in-reply-to:references:content-type :content-transfer-encoding; q=dns; s=default; b=uzjK0vjBk8m3X/QA 0MXUJh3EYy/cWNs2RoC4k6IhPyc0bF2p4QsJf35TGV6ZCHQIRwSlDEj6o7pqpCib QJWhDslW8HvqCYXLNUIyqcd/O+r5LPlQMrJyU26130BoaLn/cOgub5qd+5BolC+c 46ht/3fd7hsPjOxQ6HwGt66zSWo= 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:mime-version:in-reply-to:references:content-type :content-transfer-encoding; s=default; bh=NjMC3bZRSuwND36SrjF6FK PxIaw=; b=mw7+fohBbfkv9Ty08XkytzUu+m0b2qfhG2S3vgmwALImhx2PpiMph5 Nm9p1UlQo65Vkgh+fdycaDPWTe9crrfqCJWbRQr/bheU3mkG2yIQdxbXOcoA4Nct a+fo0BMpX5wt79F9hCqLfxyKWdqh6wamRDOw3qzCuZ1HXjxXURIeU= Received: (qmail 95746 invoked by alias); 20 Aug 2018 14:01:08 -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 94820 invoked by uid 89); 20 Aug 2018 14:00:50 -0000 Authentication-Results: sourceware.org; auth=none 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, TIME_LIMIT_EXCEEDED autolearn=unavailable version=3.3.2 spammy=user's, logging, Further, opening X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Subject: [RFC][PATCH v3 4/6] elf/dl-load.c, elf-dl-open.c: Implement RTLD_SHARED dlmopen proxying Date: Mon, 20 Aug 2018 14:54:29 +0100 Message-Id: <5b38bdbe15f0956092f7237c3c0dd80615e977fb.1534532485.git.vivek@collabora.com> In-Reply-To: References: MIME-Version: 1.0 In-Reply-To: References: This uses the new infrastructure to implement RTLD_SHARED object proxying via dlmopen: Instead of opening the specified object in the requested namespace we open it in the main namespace (if it is not already present there) and proxy it to the destination. The following rules apply: If a proxy of the object is already present in the requested namespace, we simply return it (with an incremented direct-open count). If the object is already present in the requested namespace, a dl error is signalled, since we cannot satisfy the user's request. Proxies are never created in the main namespace: RTLD_SHARED has no effect when the requested namespace is LM_ID_BASE. --- elf/dl-load.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ elf/dl-open.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 431236920f..6364030168 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1848,6 +1848,37 @@ open_path (const char *name, size_t namelen, int mode, return -1; } +/* Search for a link map proxy in the given namespace by name. + Consider it to be an error if the found object is not a proxy. */ +struct link_map * +_dl_find_proxy (Lmid_t nsid, const char *name) +{ + struct link_map *l; + + for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next) + { + if (__glibc_unlikely ((l->l_faked | l->l_removed) != 0)) + continue; + + if (!_dl_name_match_p (name, l)) + continue; + + /* We have a match - stop searching. */ + break; + } + + if (l) + { + if (l->l_proxy) + return l; + + _dl_signal_error (EEXIST, name, NULL, + N_("object cannot be demoted to a proxy")); + } + + return NULL; +} + /* Map in the shared object file NAME. */ struct link_map * @@ -1864,6 +1895,20 @@ _dl_map_object (struct link_map *loader, const char *name, assert (nsid >= 0); assert (nsid < GL(dl_nns)); +#ifdef SHARED + /* Only need to do proxy checks if `nsid' is not LM_ID_BASE. */ + if (__glibc_unlikely ((mode & RTLD_SHARED) && (nsid != LM_ID_BASE))) + { + /* Search the namespace in case the object is already proxied. */ + if((l = _dl_find_proxy (nsid, name)) != NULL) + return l; + + /* Further searches should be in the base ns: We will proxy the + resulting object in dl_open_worker *after* it is initialised. */ + nsid = LM_ID_BASE; + } +#endif + /* Look for this name among those already loaded. */ for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next) { diff --git a/elf/dl-open.c b/elf/dl-open.c index 9dde4acfbc..d28c2d2b7a 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -183,6 +183,8 @@ dl_open_worker (void *a) const char *file = args->file; int mode = args->mode; struct link_map *call_map = NULL; + int want_proxy = mode & RTLD_SHARED; + Lmid_t proxy_ns = LM_ID_BASE; /* Determine the caller's map if necessary. This is needed in case we have a DST, when we don't know the namespace ID we have to put @@ -237,6 +239,24 @@ dl_open_worker (void *a) /* This object is directly loaded. */ ++new->l_direct_opencount; + /* Proxy already existed in the target ns, nothing left to do. */ + if (__glibc_unlikely (new->l_proxy)) + { + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf ("proxied file=%s [%lu]; direct_opencount=%u\n\n", + new->l_name, new->l_ns, new->l_direct_opencount); + return; + } + + /* If we want proxy and we get this far then the entry in ‘new’ will + be in the main namespace: we should revert to the main namespace code + path(s), but remember the namespace we want the proxy to be in. */ + if (__glibc_unlikely (want_proxy)) + { + proxy_ns = args->nsid; + args->nsid = LM_ID_BASE; + } + /* It was already open. */ if (__glibc_unlikely (new->l_searchlist.r_list != NULL)) { @@ -252,6 +272,16 @@ dl_open_worker (void *a) assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); + if (__glibc_unlikely (want_proxy)) + { + args->map = new = _dl_new_proxy (new, mode, proxy_ns); + ++new->l_direct_opencount; + + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf ("proxying file=%s [%lu]; direct_opencount=%u\n\n", + new->l_name, new->l_ns, new->l_direct_opencount); + } + return; } @@ -509,6 +539,14 @@ TLS generation counter wrapped! Please report this.")); /* It failed. */ return; + if (__glibc_unlikely (want_proxy)) + { + /* args->map is the return slot which the caller sees, but keep + the original value of new hanging around so we can see the + real link map entry (for logging etc). */ + args->map = _dl_new_proxy (new, mode, proxy_ns); + ++args->map->l_direct_opencount; + } #ifndef SHARED /* We must be the static _dl_open in libc.a. A static program that has loaded a dynamic object now has competition. */ @@ -517,8 +555,16 @@ TLS generation counter wrapped! Please report this.")); /* Let the user know about the opencount. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) - _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", - new->l_name, new->l_ns, new->l_direct_opencount); + { + _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n", + new->l_name, new->l_ns, new->l_direct_opencount); + + if (args->map->l_proxy) + _dl_debug_printf ("proxying file=%s [%lu]; direct_opencount=%u\n\n", + args->map->l_name, + args->map->l_ns, + args->map->l_direct_opencount); + } } From patchwork Mon Aug 20 13:54:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 959726 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-95390-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="eIsn3fFH"; 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 41vFpL65nHz9s5c for ; Tue, 21 Aug 2018 00:01:14 +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:in-reply-to:references; q=dns; s=default; b=I3EAYsbU u8VJkH8yAZRI68EWEISGN/hdWDb/lUZLFSgUoC95LvmP6hZA5HyPlJX0rw95HM9o fJp6utT5hzukh8UHcOqhuKxMR7he5fwFCcjIzIUIwQsSus8amQ+fHeVlbeUSG8G2 QBJbNIV6ssYpzsGMQt+jwaQFP8QX6th9rNc= 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:in-reply-to:references; s=default; bh=RzmhI7SPpaGPh8 7uOIp/ddAxU/s=; b=eIsn3fFH8UO5zDOUbeqfGzCdQO1s70i9qN8LiK/lg5cg0f L2HXgYUE+n9ETuD46WJXGyiE1GMNaTKb5/9ok7w8AjZ4cfSWWBy5xorJOEbJCMVO p4k75wxh6BLBffwtwAAx3dwjnj2rlIVxUTYzHr7VvpcnR4MdpsOPiW7vKa+mU= Received: (qmail 95683 invoked by alias); 20 Aug 2018 14:01:07 -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 94819 invoked by uid 89); 20 Aug 2018 14:00:50 -0000 Authentication-Results: sourceware.org; auth=none 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, TIME_LIMIT_EXCEEDED autolearn=unavailable version=3.3.2 spammy=destroying X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Subject: [RFC][PATCH v3 5/6] elf/dl-fini.c: Handle proxy link_map entries in the shutdown path Date: Mon, 20 Aug 2018 14:54:30 +0100 Message-Id: <9314336dda6083b11b2d9f03198e7c2bde35484f.1534532485.git.vivek@collabora.com> In-Reply-To: References: In-Reply-To: References: 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; From patchwork Mon Aug 20 13:54:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 959722 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-95389-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="xT+3Arqv"; 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 41vFgg2bLsz9s5c for ; Mon, 20 Aug 2018 23:55:27 +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:in-reply-to:references; q=dns; s=default; b=vGwVywEi 9d0UxIU6cIgjjZ+8XaGRtp024HinK05icFFbeyBdrjFDmXz2ye8BI72eeOl9nBS5 kAs4BW2OJg/1nI2MyGCxPFomODff7uQkZ0r6oZjQ2GlLGtoObYYSQU2fWXULPLE8 ytDnFligmv01t5YOCVUa4S9+pctTWpfn6Sc= 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:in-reply-to:references; s=default; bh=p9uaDn4lJYL/4m G1/IyU3DhPE9g=; b=xT+3ArqvvJb6dXXjYKJf2cra+l9Ysrgmc1/atewasef3hO 61NQRrVYV/JAfQTAX+yHoWu5cIINm7XktZRXIudT2IcLQElZtOzaPzK3Gq2OvF5f /oU07eGVhv2zIYj3CqEzyjK9d+0ZjCd1iLGFXq16+LLPbtHHROCOuKywAsSdE= Received: (qmail 44165 invoked by alias); 20 Aug 2018 13:54:50 -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 44044 invoked by uid 89); 20 Aug 2018 13:54:49 -0000 Authentication-Results: sourceware.org; auth=none 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=Hx-languages-length:827 X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Subject: [RFC][PATCH v3 6/6] elf/dl-init.c: Skip proxied link map entries in the dl init path Date: Mon, 20 Aug 2018 14:54:31 +0100 Message-Id: <3aa275e3eca35f83909137c41a60af9b58e794f0.1534532485.git.vivek@collabora.com> In-Reply-To: References: In-Reply-To: References: Proxies should not trigger calls to DT_INIT constructors since they're just shims that point to the real, already loaded and initialised, objects. --- elf/dl-init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elf/dl-init.c b/elf/dl-init.c index 3e72fa3013..2533afa042 100644 --- a/elf/dl-init.c +++ b/elf/dl-init.c @@ -27,8 +27,8 @@ typedef void (*init_t) (int, char **, char **); static void call_init (struct link_map *l, int argc, char **argv, char **env) { - if (l->l_init_called) - /* This object is all done. */ + if (l->l_init_called || l->l_proxy) + /* This object is all done, or a proxy (and therefore initless). */ return; /* Avoid handling this constructor again in case we have a circular