This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] elf: Never use the file ID of the main executable [BZ #24900]
- From: Florian Weimer <fweimer at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Thu, 22 Aug 2019 18:54:59 +0200
- Subject: [PATCH] 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]").
2019-08-22 Florian Weimer <fweimer@redhat.com>
[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.
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