From patchwork Wed May 16 17:11:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 914809 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-92574-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="RzYXFqkC"; 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 40mLZN6mrbz9s2R for ; Thu, 17 May 2018 03:11:40 +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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; q=dns; s=default; b=dtil7q3kFjdjF+Ey7v/FdI0/H5d1fKRTfmWT06GA/yp 0107STajbFwKTkUnA9waVU70jOYewoM5yP83sRkug9Axe+n0CposuT0PuWuhkqQD JL4jBxkjkBdNXD6xfqrS/WPbhgDR2aoiVZcT6Cxb8agV6T8c5j6uF/N1Ad1YqAoY = 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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; s=default; bh=dICWH00KDweK0blzJ9eqg9ZviTo=; b=RzYXFqkCqNqyV6SKB QEun8Ce/vrU0KM6/87IKoyPO8cRxfY0p8qAusL6hZtuDR+GV4RCET8xHSURzLRf6 P7dpVwl2s7MI15OZYANOqWO+K0yIU4VSizJhh48Iy7roFo5RYAv2VmmBU7AVWPGQ 731HwEx1buAn3s6PX7jMmfW510= Received: (qmail 59794 invoked by alias); 16 May 2018 17:11:34 -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 58840 invoked by uid 89); 16 May 2018 17:11:33 -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=H*r:74c6, HContent-Transfer-Encoding:8bit X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Cc: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= Subject: [RFC][PATCH v1 1/5] bits/dlfcn.h: Declare and describe the dlmopen RTLD_SHARED flag Date: Wed, 16 May 2018 18:11:20 +0100 Message-Id: <20180516171124.24962-2-vivek@collabora.com> In-Reply-To: <20180516171124.24962-1-vivek@collabora.com> References: <20180516171124.24962-1-vivek@collabora.com> MIME-Version: 1.0 From: Vivek Das Mohapatra This flag will instruct dlmopen to create a shared object present in both the main namespace and the selected namespace when set. --- bits/dlfcn.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bits/dlfcn.h b/bits/dlfcn.h index b0b129b66b..a96270d499 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 (clone) 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. */ From patchwork Wed May 16 17:11:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 914811 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-92576-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="dNeT9g/p"; 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 40mLZk1w6sz9s2R for ; Thu, 17 May 2018 03:11:58 +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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; q=dns; s=default; b=P11zt28mlRDbhUujZI26/A9NGZGrQVHmqJ4GoiGTSbT hmkc5TjixzojzRhsMbnHxGDd4WU2KVFiTNWeSR1w96tMGoX6eIBVUQSbzksaTHkq pbGeQVO1XIWEULZwCfPMrayNJR4VTkw9PFBC/ZkLuaEpfG9vJmNaO1UoeuxFgZcU = 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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; s=default; bh=1kP4/1GY9hZwMpEYoABOUdGDxJI=; b=dNeT9g/pcLETFqvM0 obJGP0sF94ZkAcFB9zvjKSf4lDTMeuuyHEWrcIV50KQIU+WO9RuQYe0X4dZJsH/S julUjzPg+jhYs7Kg6QU9IJyY+qfwjrpKeKjkj7tBfdeCNkpQDT+ikG5J0droG4Cu rpDSfuKgQ5Gx0dupMNt8uAu7NM= Received: (qmail 60368 invoked by alias); 16 May 2018 17:11:35 -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 58839 invoked by uid 89); 16 May 2018 17:11:33 -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=H*r:74c6, reserved, HContent-Transfer-Encoding:8bit X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Cc: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= Subject: [RFC][PATCH v1 2/5] include/link.h: Update the link_map struct to allow clones Date: Wed, 16 May 2018 18:11:21 +0100 Message-Id: <20180516171124.24962-3-vivek@collabora.com> In-Reply-To: <20180516171124.24962-1-vivek@collabora.com> References: <20180516171124.24962-1-vivek@collabora.com> MIME-Version: 1.0 From: Vivek Das Mohapatra 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 clone. --- include/link.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/link.h b/include/link.h index 5924594548..e051b5cd36 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 cloned 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_clone:1; /* Nonzero if object is a clone. */ 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 Wed May 16 17:11:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 914810 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-92575-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="a+Gwb+he"; 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 40mLZY4jVJz9s2R for ; Thu, 17 May 2018 03:11:49 +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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; q=dns; s=default; b=iFxoFqBd1T2YptHlSb4MbBzttqG130w+/aWEpXOSPgo YbTq0APD9xrdFokoiTeH0XgTAFxemSWXpv8xA+/ryiTJst3gfhWbIheTkFTdKP75 f0YOQ7VyudKNt7mIcazYVXTA47bK0vaiDRmmcl0yRganGDeHGAsS5jTlgfKSHSTs = 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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; s=default; bh=dOIIWHFusSEq4ce4GOoLEn30iQM=; b=a+Gwb+he69YtLZNgz XKqgP96ENZWevuRyFt3b4XKbRD08yY7ZhOWxG9qO+nXZe+kbCQp3jrcnVlj4rtuA R/IUS9Gfz7PPlQXgBqXiaTyvNCP150dPRIq4dT+zOQBUBch/1oWeehsVDWqaDu89 rrdSwOpcunAPyrV3ZbQ78zLuzQ= Received: (qmail 60236 invoked by alias); 16 May 2018 17:11:35 -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 59383 invoked by uid 89); 16 May 2018 17:11:34 -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=arrived, H*r:74c6, HContent-Transfer-Encoding:8bit X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Cc: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= Subject: [RFC][PATCH v1 3/5] elf/dl-object.c: Implement a helper function to clone link_map entries Date: Wed, 16 May 2018 18:11:22 +0100 Message-Id: <20180516171124.24962-4-vivek@collabora.com> In-Reply-To: <20180516171124.24962-1-vivek@collabora.com> References: <20180516171124.24962-1-vivek@collabora.com> MIME-Version: 1.0 From: Vivek Das Mohapatra Provides the minimal functionality needed to take an existing link_map entry and create a clone of it in the specified namespace. --- elf/dl-object.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++ sysdeps/generic/ldsodefs.h | 6 ++++ 2 files changed, 83 insertions(+) diff --git a/elf/dl-object.c b/elf/dl-object.c index b37bcc1295..144ba6c993 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -50,6 +51,82 @@ _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid) __rtld_lock_unlock_recursive (GL(dl_load_write_lock)); } +/* Clone 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 clones). + It also flags the clone by setting l_clone, and sets the the no-delete + flag in the original. */ +struct link_map * +_dl_clone_object (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 this number is arrived at: */ + unsigned int na = GLRO(dl_naudit) ?: ((mode & __RTLD_OPENEXEC) ? DL_NNS : 0); + size_t audit_space = na * sizeof (new->l_audit[0]); +#else +# define audit_space 0 +#endif + + name = old->l_name; + + /* Don't clone a clone: Go to the progenitor. */ + while (old && old->l_clone) + old = old->l_real; + + if (old == NULL) + _dl_signal_error (EINVAL, name, NULL, N_("cannot clone 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_clone) + return old; + + _dl_signal_error (EEXIST, name, NULL, + N_("object cannot be demoted to a clone")); + } + + /* Now duplicate as little of _dl_new_object as possible to get a + working cloned object in the target link map. */ + new = (struct link_map *) calloc (sizeof (*new) + audit_space + + sizeof (struct link_map *) + + sizeof (*newname) + PATH_MAX, 1); + + /* Specific to the clone. */ + new->l_real = old; + new->l_clone = 1; + new->l_ns = nsid; + + /* Copied from the origin. */ + new->l_libname = old->l_libname; + new->l_name = old->l_name; + new->l_type = 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 clone remains valid. */ + old->l_flags_1 |= DF_1_NODELETE; + + /* Fix up the searchlist so that relocations work. */ + /* TODO: figure out if we should call _dl_map_object_deps + or copy the contents of l_scope, l_searchlist et al. */ + _dl_map_object_deps (new, NULL, 0, 0, + mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT)); + + /* And finally put the clone into 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 5e1b24ecb5..573d24f611 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -913,6 +913,12 @@ extern lookup_t _dl_lookup_symbol_x (const char *undef, extern void _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid) attribute_hidden; +/* Clone an existing link map entry into a new link map */ +extern struct link_map *_dl_clone_object (struct link_map *old, + int mode, + Lmid_t nsid) + attribute_hidden; + /* Allocate a `struct link_map' for a new object being loaded. */ extern struct link_map *_dl_new_object (char *realname, const char *libname, int type, struct link_map *loader, From patchwork Wed May 16 17:11:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 914814 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-92579-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="mdmS0J25"; 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 40mLlX10dQz9s2R for ; Thu, 17 May 2018 03:19:35 +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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; q=dns; s=default; b=Kq+00TeECelAgIbKqIDKwHSIVXMcj4czXU8nn3b7jRf A0oksyNSmOCw0QoYVjjf33O3TI7psmx9vuzqH6rmYtLA4Zr2bglgg5vo8MteUtWD WuP5kGtpf0An0u/9ZmjbUCjOuj851s8OhiTBZiV09YHWb5+vJAwhQgHuxqRWj3HU = 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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; s=default; bh=U2yot+htERBUWPPlv3qnybyablY=; b=mdmS0J25/QujdOQ7+ o9D4ueVblfJv4sGdbkaknYQHpPS2nD+qljWx6JxQGy3KnvxtogqbsARV6rkDedIg yu2EUNmo5zAW4Llh2OORugRY/puykIRpJeUzIXyaCYzJXls1TT6NrXMEpMK9IwBE g3GkvShu6UxzwfAND8KhUhm4Cg= Received: (qmail 38785 invoked by alias); 16 May 2018 17:19:30 -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 38769 invoked by uid 89); 16 May 2018 17:19:29 -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=Further, initialised, competition X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Cc: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= Subject: [RFC][PATCH v1 4/5] elf/dl-load.c, elf-dl-open.c: Implement RTLD_SHARED dlmopen cloning Date: Wed, 16 May 2018 18:11:23 +0100 Message-Id: <20180516171124.24962-5-vivek@collabora.com> In-Reply-To: <20180516171124.24962-1-vivek@collabora.com> References: <20180516171124.24962-1-vivek@collabora.com> MIME-Version: 1.0 From: Vivek Das Mohapatra This uses the new infrastructure to implement RTLD_SHARED object cloning 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 clone it into the requated namespace. The following rules apply: If a clone 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. Clones are never created in the main namespace: RTLD_SHARED has no effect when the requested namespace is LM_ID_BASE. --- elf/dl-load.c | 34 ++++++++++++++++++++++++++++++++++ elf/dl-open.c | 31 +++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index a5e3a25462..a3bc85fb0a 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1847,6 +1847,40 @@ _dl_map_object (struct link_map *loader, const char *name, assert (nsid >= 0); assert (nsid < GL(dl_nns)); +#ifdef SHARED + /* Only need to do cloning work if `nsid' is not LM_ID_BASE. */ + if (__glibc_unlikely ((mode & RTLD_SHARED) && (nsid != LM_ID_BASE))) + { + /* Search the target namespace, in case the object is already there. + Note that unlike the search in the next section we do not attempt to + extract the object's name if it does not yet have one. */ + 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_clone) + return l; + + _dl_signal_error (EEXIST, name, NULL, + N_("object cannot be demoted to a clone")); + } + + /* Further searches should be in the base ns: We will clone 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..0c5c75c137 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -237,6 +237,10 @@ dl_open_worker (void *a) /* This object is directly loaded. */ ++new->l_direct_opencount; + /* Clone already existed in the target ns, nothing left to do. */ + if (__glibc_unlikely (new->l_clone)) + return; + /* It was already open. */ if (__glibc_unlikely (new->l_searchlist.r_list != NULL)) { @@ -252,6 +256,16 @@ dl_open_worker (void *a) assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); + if (__glibc_unlikely (mode & RTLD_SHARED)) + { + args->map = new = _dl_clone_object (new, mode, args->nsid); + ++new->l_direct_opencount; + + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf ("cloning file=%s [%lu]; direct_opencount=%u\n\n", + new->l_name, new->l_ns, new->l_direct_opencount); + } + return; } @@ -509,6 +523,11 @@ TLS generation counter wrapped! Please report this.")); /* It failed. */ return; + if (__glibc_unlikely (mode & RTLD_SHARED)) + { + args->map = _dl_clone_object (new, mode, args->nsid); + ++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 +536,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 (mode & RTLD_SHARED) + _dl_debug_printf ("cloning file=%s [%lu]; direct_opencount=%u\n\n", + args->map->l_name, + args->map->l_ns, + args->map->l_direct_opencount); + } } From patchwork Wed May 16 17:11:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vivek Dasmohapatra X-Patchwork-Id: 914813 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-92578-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="c/0xRLNr"; 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 40mLb40xdQz9s2R for ; Thu, 17 May 2018 03:12:15 +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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; q=dns; s=default; b=N6CxPXudoaKP294nx/oIV+LrTISvcK3uVOuFYHMlvNg BTrzC/4O4CD8REGkbm6bCRp8E8Av3vJt6GDQgN9pzD0kY9C+jIIEe68EbZMhSWfR gs4M/snJB/CidmTqVkAjnnmBQwSQ64ig8d7dtW3fwjQsyUwuO5lWGIB59a473OM4 = 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:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; s=default; bh=Rpu/HVDd1PWm3HnX22ddePNtrck=; b=c/0xRLNrzcldmZ9aw 3uxJYEup5WeGI03jouSUEE0lX1DxAIZay0/wxOCcUg+P8saiqZbA9YY5O5Y5JZF1 kCtoBoEfWanxi2VitrjJ+WayPaEgT/8U9TpklR9e7Ty+ZHX1Q38KxzhO5OLNQVR6 4JWR8BHQAhp3Wu5CciJB2sVlMM= Received: (qmail 60928 invoked by alias); 16 May 2018 17:11:38 -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 60776 invoked by uid 89); 16 May 2018 17:11:37 -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=2450, auditing, Protect, directions X-HELO: bhuna.collabora.co.uk From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= To: libc-alpha@sourceware.org Cc: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= Subject: [RFC][PATCH v1 5/5] elf/dl-fini.c: Handle cloned link_map entries in the shutdown path Date: Wed, 16 May 2018 18:11:24 +0100 Message-Id: <20180516171124.24962-6-vivek@collabora.com> In-Reply-To: <20180516171124.24962-1-vivek@collabora.com> References: <20180516171124.24962-1-vivek@collabora.com> MIME-Version: 1.0 From: Vivek Das Mohapatra When cleaning up before exit we should not call destructors or otherwise free [most of] the contents of a cloned link_map entry since they share [most of] their contents with the LM_ID_BASE object from which they were cloned. Instead we do the minimal cleanup necessary and remove them from the namespace linked list(s) before the main cleanup code path is triggered: This prevemts double-frees and double-invocation of any destructors (which might not be idempotent). --- elf/dl-fini.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/elf/dl-fini.c b/elf/dl-fini.c index 3cfc262400..643a68504e 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -24,6 +24,50 @@ /* Type of the constructor functions. */ typedef void (*fini_t) (void); +/* Remove (and free) cloned entries from the namespace specifid by `ns'. */ +void +_dl_forget_clones (Lmid_t ns) +{ +#ifdef SHARED /* Obviously none of this applies if */ + struct link_map *clone; + struct link_map *next; + + if (ns < 0 || ns >= DL_NNS) + return; + + for (clone = GL(dl_ns)[ns]._ns_loaded; clone != NULL; clone = next) + { + next = clone->l_next; + + /* Not actually clone, don't care. */ + if (!clone->l_clone) + continue; + + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) + _dl_debug_printf ("\nclone removed %s [%lu]\n", clone->l_name, ns); + + /* If item is a clone, slice it out of the linked list. */ + if (clone == GL(dl_ns)[ns]._ns_loaded) + GL(dl_ns)[ns]._ns_loaded = clone->l_next; + else + clone->l_prev->l_next = clone->l_next; + + /* Remember to fix up the links in both directions. */ + if (clone->l_next) + clone->l_next->l_prev = clone->l_prev; + + /* Don't need to do most destructor handling for clones. */ + if (clone->l_free_initfini) + free (clone->l_initfini); + + /* Do need to fix the global load count which is updated in + _dl_add_to_namespace_list. */ + GL(dl_ns)[ns]._ns_nloaded--; + + free (clone); + } +#endif +} void _dl_fini (void) @@ -52,6 +96,12 @@ _dl_fini (void) /* Protect against concurrent loads and unloads. */ __rtld_lock_lock_recursive (GL(dl_load_lock)); + /* We need to remove any pointers to cloned entries (link_map + structs that are copied from one namespace to another to + implement RTLD_SHARED semantics) before the regular cleanup + code gets to them. */ + _dl_forget_clones (ns); + unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded; /* No need to do anything for empty namespaces or those used for auditing DSOs. */