aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2019-10-04 21:22:54 +0200
committerFlorian Weimer <fweimer@redhat.com>2019-10-04 21:22:54 +0200
commit2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59 (patch)
tree4e22bfbb8197ffdbf3fb5d86b3613dee441d8491 /elf
parenteaad14b56aa0d18b3b6bbb1618de2ab5b242d434 (diff)
downloadglibc-2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59.zip
glibc-2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59.tar.gz
glibc-2b26b084e4e4ba58a2ff9f8f8f14c9bca506bd59.tar.bz2
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')
-rw-r--r--elf/dl-load.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 21a91b9..8f19203 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