From patchwork Thu Aug 22 16:54:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 34246 Received: (qmail 81900 invoked by alias); 22 Aug 2019 16:55:04 -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 81891 invoked by uid 89); 22 Aug 2019 16:55:04 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=Never, lose X-HELO: mx1.redhat.com From: Florian Weimer To: libc-alpha@sourceware.org Subject: [PATCH] elf: Never use the file ID of the main executable [BZ #24900] Date: Thu, 22 Aug 2019 18:54:59 +0200 Message-ID: <87pnkxw36k.fsf@oldenburg2.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 If the loader is invoked explicitly and loads the main executable, it stores the file ID of the main executable in l_file_id. This information is not available if the main excutable is loaded by the kernel, so this is another case where the two cases differ. This enhances commit 23d2e5faf0bca6d9b31bef4aa162b95ee64cbfc6 ("elf: Self-dlopen failure with explict loader invocation [BZ #24900]"). 2019-08-22 Florian Weimer [BZ #24900] * elf/dl-load.c (_dl_map_object_from_fd): Do not use the file ID when loading the executable as part of an explicit loader invocation. Reviewed-by: Gabriel F. T. Gomes diff --git a/elf/dl-load.c b/elf/dl-load.c index 5abeb867f1..7bf0ca563e 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -876,33 +876,43 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, struct r_debug *r = _dl_debug_initialize (0, nsid); bool make_consistent = false; - /* Get file information. */ + /* Get file information. To match the kernel behavior, do not fill + in this information for the executable in case of an explicit + loader invocation. */ struct r_file_id id; - if (__glibc_unlikely (!_dl_get_file_id (fd, &id))) + if (mode & __RTLD_OPENEXEC) { - errstring = N_("cannot stat shared object"); - call_lose_errno: - errval = errno; - call_lose: - lose (errval, fd, name, realname, l, errstring, - make_consistent ? r : NULL, nsid); + assert (nsid == LM_ID_BASE); + memset (&id, 0, sizeof (id)); } + else + { + if (__glibc_unlikely (!_dl_get_file_id (fd, &id))) + { + errstring = N_("cannot stat shared object"); + call_lose_errno: + errval = errno; + call_lose: + lose (errval, fd, name, realname, l, errstring, + make_consistent ? r : NULL, nsid); + } - /* Look again to see if the real name matched another already loaded. */ - for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next) - if (!l->l_removed && _dl_file_id_match_p (&l->l_file_id, &id)) - { - /* The object is already loaded. - Just bump its reference count and return it. */ - __close_nocancel (fd); + /* Look again to see if the real name matched another already loaded. */ + for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next) + if (!l->l_removed && _dl_file_id_match_p (&l->l_file_id, &id)) + { + /* The object is already loaded. + Just bump its reference count and return it. */ + __close_nocancel (fd); - /* If the name is not in the list of names for this object add - it. */ - free (realname); - add_name_to_object (l, name); + /* If the name is not in the list of names for this object add + it. */ + free (realname); + add_name_to_object (l, name); - return l; - } + return l; + } + } #ifdef SHARED /* When loading into a namespace other than the base one we must