From: Florian Weimer Date: Fri, 4 Oct 2019 19:22:54 +0000 (+0200) Subject: elf: Never use the file ID of the main executable [BZ #24900] X-Git-Tag: changelog-ends-here~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59;p=thirdparty%2Fglibc.git elf: Never use the file ID of the main executable [BZ #24900] 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]"). Reviewed-by: Carlos O'Donell Reviewed-by: Gabriel F. T. Gomes --- diff --git a/ChangeLog b/ChangeLog index a91af5403d1..d2156e5fb08 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2019-10-04 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. + 2019-10-04 Florian Weimer nptl: Move pthread_attr_setinheritsched implementation into libc. diff --git a/elf/dl-load.c b/elf/dl-load.c index 21a91b9484c..8f192036a51 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