]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
elf: Never use the file ID of the main executable [BZ #24900]
authorFlorian Weimer <fweimer@redhat.com>
Fri, 4 Oct 2019 19:22:54 +0000 (21:22 +0200)
committerFlorian Weimer <fweimer@redhat.com>
Fri, 4 Oct 2019 19:22:54 +0000 (21:22 +0200)
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>
ChangeLog
elf/dl-load.c

index a91af5403d1684dcbc4fa3e1ed527cdcc723982c..d2156e5fb0829695dc8aaa7e0e4d740eab4ee2bd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2019-10-04  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.
+
 2019-10-04  Florian Weimer  <fweimer@redhat.com>
 
        nptl: Move pthread_attr_setinheritsched implementation into libc.
index 21a91b9484cd5d98bbbab45ef4e8e38cb45cce33..8f192036a51b5cb9258076ab3c6310bc5721faf2 100644 (file)
@@ -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