From patchwork Mon Jan 6 15:42:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Viennot X-Patchwork-Id: 1218255 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-108457-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=twosigma.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="EeEpuudW"; 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 47s0Bl1FnMz9s29 for ; Tue, 7 Jan 2020 02:42:38 +1100 (AEDT) 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:content-type :content-transfer-encoding:mime-version; q=dns; s=default; b=DGY uI06w0bz3liFqveZpKU6dXFh49h24r/aUPcDePbcYTWW0cWaUw+sE7EjxqmrY1nB la44e5MnLs9IBXlpx0dZEUITQNyMpFVyQbidx4WD9vcQ4AEd9BKy7IzEbVguRqZ0 ifqMBV7LOZEJWXMnESsUNjM8Z9snDOV8rsaS9FP4= 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:content-type :content-transfer-encoding:mime-version; s=default; bh=YpEz8sf+7 3AP7plyCMf6Cy6luKs=; b=EeEpuudWLKJh3gCR06CC5TJArlPENEMKBsOJPNlGO o7tSbzFLFepXZTf/yA+tlEB3NgaWVvSLSlD00DEtGntuoauLVkEVqsKfpDcQev3v SM6X5wxLMo12Q/j3TkVMisZp52gEM+HC4h2hQwejj0+uv255/RBvaNI42a/fJsuf 4E= Received: (qmail 37511 invoked by alias); 6 Jan 2020 15:42:33 -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 37503 invoked by uid 89); 6 Jan 2020 15:42:33 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-9.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=Display X-HELO: mxo1.dft.dmz.twosigma.com From: Nicolas Viennot To: "libc-alpha@sourceware.org" Subject: [PATCH 1/3] dl-load: extract _dl_find_object_from_name() from _dl_map_object() Date: Mon, 6 Jan 2020 15:42:29 +0000 Message-ID: <61c0b49f4d7342a48743d0de82a5429d@EXMBDFT10.ad.twosigma.com> MIME-Version: 1.0 --- elf/dl-load.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 6cdd11e6b0..c436a447af 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1906,21 +1906,11 @@ open_path (const char *name, size_t namelen, int mode, /* Map in the shared object file NAME. */ -struct link_map * -_dl_map_object (struct link_map *loader, const char *name, - int type, int trace_mode, int mode, Lmid_t nsid) +static struct link_map * +_dl_find_object_from_name(const char *name, Lmid_t nsid) { - int fd; - const char *origname = NULL; - char *realname; - char *name_copy; struct link_map *l; - struct filebuf fb; - assert (nsid >= 0); - assert (nsid < GL(dl_nns)); - - /* Look for this name among those already loaded. */ for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next) { /* If the requested name matches the soname of a loaded object, @@ -1950,6 +1940,28 @@ _dl_map_object (struct link_map *loader, const char *name, return l; } + return NULL; +} + +struct link_map * +_dl_map_object (struct link_map *loader, const char *name, + int type, int trace_mode, int mode, Lmid_t nsid) +{ + int fd; + const char *origname = NULL; + char *realname; + char *name_copy; + struct link_map *l; + struct filebuf fb; + + assert (nsid >= 0); + assert (nsid < GL(dl_nns)); + + /* Look for this name among those already loaded. */ + l = _dl_find_object_from_name(name, nsid); + if (l != NULL) + return l; + /* Display information if we are debugging. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES) && loader != NULL) From patchwork Mon Jan 6 15:44:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Viennot X-Patchwork-Id: 1218256 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-108458-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=twosigma.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="Q30cAJtU"; 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 47s0Dt5z6Vz9s29 for ; Tue, 7 Jan 2020 02:44:30 +1100 (AEDT) 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:content-type :content-transfer-encoding:mime-version; q=dns; s=default; b=wpl nbel9Q+VvJ9o6hPxychs79kLERg1ywJW8xwIz4YnmmDvXs8ELMcKlVryl9koA/v7 jUlWvD77lHIfHFspmsivnqh6n+KmLHNgTx+SBZ4Z0vSWyhwaSMy30KaId2bIu3jb z066U8eTEsGgNMaYmLV75k3ThkNYXoqjI9ZKHPwY= 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:content-type :content-transfer-encoding:mime-version; s=default; bh=OBJoQBawM ncZwFaW53ijOCq34m0=; b=Q30cAJtU3etC9Eq+yquPA4Nd/f0K8eP3nDAkqYQh5 pvZW0uQ9cFVRIsujBbG9niwlTowJbTQ8Qr7ZIoO7g2IQ3Zzefkk4ju8IYjYnzPlo tp7reBZYUOUpThY/Mv/PIvx2ESSLw6AledWzJCZ0zHBIASoFSx9AAfxGseWT+mgQ b0= Received: (qmail 43408 invoked by alias); 6 Jan 2020 15:44:24 -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 43400 invoked by uid 89); 6 Jan 2020 15:44:24 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy= X-HELO: mxo1.nje.dmz.twosigma.com From: Nicolas Viennot To: "libc-alpha@sourceware.org" Subject: [PATCH 2/3] dl-load: enforce soname uniqueness of loaded libraries Date: Mon, 6 Jan 2020 15:44:20 +0000 Message-ID: <8a449dd92e5f41189f95abbe803c82e3@EXMBDFT10.ad.twosigma.com> MIME-Version: 1.0 When loading a new library of name `libname`, the loader currently checks if any of the already loaded libraries have the soname `libname`. If so, it returns the already loaded library of soname `libname`. If not, it checks for the corresponding file `libname` on disk and compares the device and inode number of already loaded libraries. If there is a match, it returns the already loaded library of the same inode number. If not, it proceeds to load the library of path is `libname`. This patch adds the additional check of comparing the soname of the newly loaded library with the sonames of already loaded libraries. This new behavior enforces that no two loaded libaries have the same soname, bringing a sane property in the system. Note that this edge case can be encountered during a system upgrade, or when using certain configuration of file system mounts, where inodes cannot be relied upon. --- elf/dl-load.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/elf/dl-load.c b/elf/dl-load.c index c436a447af..c5c997f95b 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -851,6 +851,8 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l, _dl_signal_error (code, name, NULL, msg); } +static struct link_map * +_dl_find_object_from_name(const char *name, Lmid_t nsid); /* Map in the shared object NAME, actually located in REALNAME, and already opened on FD. */ @@ -1202,6 +1204,52 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, elf_get_dynamic_info (l, NULL); + /* + * Check if we have a loaded object with the same soname. If that's the + * case, return the previously loaded object. The loop follows a similar + * logic compared to the beginning of _dl_map_object(). + * the loader assumes that the sonames of loaded objects are without + * duplicates. + */ + + if (l->l_info[DT_SONAME] != NULL) + { + static struct link_map *_l; + const char *soname; + + soname = (((const char *) D_PTR (l, l_info[DT_STRTAB]) + + l->l_info[DT_SONAME]->d_un.d_val)); + + _l = _dl_find_object_from_name(soname, nsid); + if (__glibc_unlikely(_l != NULL)) + { + /* Free current object */ + _dl_unmap_segments (l); + + if (!l->l_libname->dont_free) + free (l->l_libname); + + if (l->l_phdr_allocated) + free ((void *) l->l_phdr); + + __close_nocancel (fd); + if (l->l_origin != (char *) -1l) + free ((char *) l->l_origin); + free (l); + free (realname); + + if (make_consistent) + { + r->r_state = RT_CONSISTENT; + _dl_debug_state (); + } + + /* Cache the name and return the previously loaded object */ + add_name_to_object (_l, name); + return _l; + } + } + /* Make sure we are not dlopen'ing an object that has the DF_1_NOOPEN flag set, or a PIE object. */ if ((__glibc_unlikely (l->l_flags_1 & DF_1_NOOPEN) From patchwork Mon Jan 6 15:45:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Viennot X-Patchwork-Id: 1218258 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-108459-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=twosigma.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="OlxWXonc"; 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 47s0G15RS5z9s29 for ; Tue, 7 Jan 2020 02:45:29 +1100 (AEDT) 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:content-type :content-transfer-encoding:mime-version; q=dns; s=default; b=Zph vu15JgEsZ+CrmD7rC5acfLO5CM7jIvMvycoDKTAnDc8/qtAVNrKddPUaaju25jxT sdYSlSHzYQFduLcrMUekWR1MYtyjILG/qPsFJtss1oaWXyx+179nLs2472sO1A0p 84L0G20SydgJL7u/Ocx/WhmZtDEGuPtjHAwtLbDc= 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:content-type :content-transfer-encoding:mime-version; s=default; bh=wCkqvVCHi dPmrd+Odx5NUr+7xdE=; b=OlxWXoncIVR45TM+UVmv64/IwM/UgQH8/l90K1+S9 oDP4sM2/d+QjMA8+aMs8tV/DIi+FwSMALr0WSHJmSkigVf4CRa1p/OTdvLnwLiQ4 mVZlVSzKg40Lqt5gdC8kzCbnI3FAgAHV3ApKG7GbZjiVzE8hre+HXQvV/Xbbyuzb hg= Received: (qmail 45577 invoked by alias); 6 Jan 2020 15:45:23 -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 45422 invoked by uid 89); 6 Jan 2020 15:45:17 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=1998, libdl, 1997 X-HELO: mxo2.dft.dmz.twosigma.com From: Nicolas Viennot To: "libc-alpha@sourceware.org" Subject: [PATCH 3/3] dl-load: test that loaded libraries cannot have duplicated sonames Date: Mon, 6 Jan 2020 15:45:06 +0000 Message-ID: <8fd944a7c6d74ef3868a3fec7aae625e@EXMBDFT10.ad.twosigma.com> MIME-Version: 1.0 --- elf/Makefile | 14 +++++++++++++- elf/tst-dlopen-soname-dup.c | 34 ++++++++++++++++++++++++++++++++++ elf/tst-soname-mod.c | 19 +++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 elf/tst-dlopen-soname-dup.c create mode 100644 elf/tst-soname-mod.c diff --git a/elf/Makefile b/elf/Makefile index f861126b2f..88a7361073 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -199,7 +199,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ tst-unwind-ctor tst-unwind-main tst-audit13 \ tst-sonamemove-link tst-sonamemove-dlopen tst-dlopen-tlsmodid \ - tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail + tst-dlopen-self tst-auditmany tst-initfinilazyfail tst-dlopenfail \ + tst-dlopen-soname-dup # reldep9 tests-internal += loadtest unload unload2 circleload1 \ neededtest neededtest2 neededtest3 neededtest4 \ @@ -305,6 +306,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib \ tst-audit13mod1 tst-sonamemove-linkmod1 \ tst-sonamemove-runmod1 tst-sonamemove-runmod2 \ + tst-soname-mod \ tst-auditmanymod1 tst-auditmanymod2 tst-auditmanymod3 \ tst-auditmanymod4 tst-auditmanymod5 tst-auditmanymod6 \ tst-auditmanymod7 tst-auditmanymod8 tst-auditmanymod9 \ @@ -1499,6 +1501,16 @@ $(objpfx)tst-sonamemove-dlopen.out: \ $(objpfx)tst-sonamemove-runmod1.so \ $(objpfx)tst-sonamemove-runmod2.so +LDFLAGS-tst-soname-mod.so = -Wl,-soname=dummyname + +$(objpfx)tst-soname-mod-copy.so: $(objpfx)tst-soname-mod.so + cp $< $@ + +$(objpfx)tst-dlopen-soname-dup: $(libdl) +$(objpfx)tst-dlopen-soname-dup.out: \ + $(objpfx)tst-soname-mod.so \ + $(objpfx)tst-soname-mod-copy.so + # Override -z defs, so that we can reference an undefined symbol. # Force lazy binding for the same reason. LDFLAGS-tst-latepthreadmod.so = \ diff --git a/elf/tst-dlopen-soname-dup.c b/elf/tst-dlopen-soname-dup.c new file mode 100644 index 0000000000..804b259f3f --- /dev/null +++ b/elf/tst-dlopen-soname-dup.c @@ -0,0 +1,34 @@ +/* Check that two DSOs with the same soname can only be loaded once + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +static int +do_test (void) +{ + void *h1 = xdlopen ("tst-soname-mod.so", RTLD_NOW); + void *h2 = xdlopen ("tst-soname-mod-copy.so", RTLD_NOW); + + TEST_VERIFY (h1 == h2); + + return 0; +} + +#include diff --git a/elf/tst-soname-mod.c b/elf/tst-soname-mod.c new file mode 100644 index 0000000000..844438a146 --- /dev/null +++ b/elf/tst-soname-mod.c @@ -0,0 +1,19 @@ +/* Run-time module with a soname defined + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* left intentionally blank */