diff options
author | Florian Weimer <fweimer@redhat.com> | 2019-10-04 21:22:54 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2019-10-04 21:22:54 +0200 |
commit | 2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59 (patch) | |
tree | 4e22bfbb8197ffdbf3fb5d86b3613dee441d8491 /elf/dl-load.c | |
parent | eaad14b56aa0d18b3b6bbb1618de2ab5b242d434 (diff) | |
download | glibc-2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59.tar glibc-2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59.tar.gz glibc-2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59.tar.bz2 glibc-2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59.zip |
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 <carlos@redhat.com>
Reviewed-by: Gabriel F. T. Gomes <gabrielftg@linux.ibm.com>
Diffstat (limited to 'elf/dl-load.c')
-rw-r--r-- | elf/dl-load.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c index 21a91b9484..8f192036a5 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 |