dfa500
Partial backport without the new tst-dlopen-aout-pie test.  The test
dfa500
fails because the a self-dlopen of a PIE binary succeeds, as commit
dfa500
23d2e5faf0bca6d9b31bef4aa162b95ee64cbfc6 ("elf: Self-dlopen failure
dfa500
with explict loader invocation [BZ #24900]") has not been backported.
dfa500
dfa500
commit 77523d5e43cb5721c23855eb6045b0607a3b30a0
dfa500
Author: Florian Weimer <fweimer@redhat.com>
dfa500
Date:   Fri Oct 4 21:23:51 2019 +0200
dfa500
dfa500
    elf: Assign TLS modid later during dlopen [BZ #24930]
dfa500
    
dfa500
    Commit a42faf59d6d9f82e5293a9ebcc26d9c9e562b12b ("Fix BZ #16634.")
dfa500
    attempted to fix a TLS modid consistency issue by adding additional
dfa500
    checks to the open_verify function.  However, this is fragile
dfa500
    because open_verify cannot reliably predict whether
dfa500
    _dl_map_object_from_fd will later fail in the more complex cases
dfa500
    (such as memory allocation failures).  Therefore, this commit
dfa500
    assigns the TLS modid as late as possible.  At that point, the link
dfa500
    map pointer will eventually be passed to _dl_close, which will undo
dfa500
    the TLS modid assignment.
dfa500
    
dfa500
    Reviewed-by: Gabriel F. T. Gomes <gabrielftg@linux.ibm.com>
dfa500
dfa500
diff --git a/elf/dl-load.c b/elf/dl-load.c
dfa500
index bb839ef70ff46f37..b190b28e32e47391 100644
dfa500
--- a/elf/dl-load.c
dfa500
+++ b/elf/dl-load.c
dfa500
@@ -1134,27 +1134,21 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
dfa500
 	     offset.  We will adjust it later.  */
dfa500
 	  l->l_tls_initimage = (void *) ph->p_vaddr;
dfa500
 
dfa500
-	  /* If not loading the initial set of shared libraries,
dfa500
-	     check whether we should permit loading a TLS segment.  */
dfa500
-	  if (__glibc_likely (l->l_type == lt_library)
dfa500
-	      /* If GL(dl_tls_dtv_slotinfo_list) == NULL, then rtld.c did
dfa500
-		 not set up TLS data structures, so don't use them now.  */
dfa500
-	      || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL))
dfa500
-	    {
dfa500
-	      /* Assign the next available module ID.  */
dfa500
-	      l->l_tls_modid = _dl_next_tls_modid ();
dfa500
-	      break;
dfa500
-	    }
dfa500
+	  /* l->l_tls_modid is assigned below, once there is no
dfa500
+	     possibility for failure.  */
dfa500
 
dfa500
+	  if (l->l_type != lt_library
dfa500
+	      && GL(dl_tls_dtv_slotinfo_list) == NULL)
dfa500
+	    {
dfa500
 #ifdef SHARED
dfa500
-	  /* We are loading the executable itself when the dynamic
dfa500
-	     linker was executed directly.  The setup will happen
dfa500
-	     later.  Otherwise, the TLS data structures are already
dfa500
-	     initialized, and we assigned a TLS modid above.  */
dfa500
-	  assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0);
dfa500
+	      /* We are loading the executable itself when the dynamic
dfa500
+		 linker was executed directly.  The setup will happen
dfa500
+		 later.  */
dfa500
+	      assert (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0);
dfa500
 #else
dfa500
-	  assert (false && "TLS not initialized in static application");
dfa500
+	      assert (false && "TLS not initialized in static application");
dfa500
 #endif
dfa500
+	    }
dfa500
 	  break;
dfa500
 
dfa500
 	case PT_GNU_STACK:
dfa500
@@ -1395,6 +1389,18 @@ cannot enable executable stack as shared object requires");
dfa500
     add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB])
dfa500
 			    + l->l_info[DT_SONAME]->d_un.d_val));
dfa500
 
dfa500
+  /* _dl_close can only eventually undo the module ID assignment (via
dfa500
+     remove_slotinfo) if this function returns a pointer to a link
dfa500
+     map.  Therefore, delay this step until all possibilities for
dfa500
+     failure have been excluded.  */
dfa500
+  if (l->l_tls_blocksize > 0
dfa500
+      && (__glibc_likely (l->l_type == lt_library)
dfa500
+	  /* If GL(dl_tls_dtv_slotinfo_list) == NULL, then rtld.c did
dfa500
+	     not set up TLS data structures, so don't use them now.  */
dfa500
+	  || __glibc_likely (GL(dl_tls_dtv_slotinfo_list) != NULL)))
dfa500
+    /* Assign the next available module ID.  */
dfa500
+    l->l_tls_modid = _dl_next_tls_modid ();
dfa500
+
dfa500
 #ifdef DL_AFTER_LOAD
dfa500
   DL_AFTER_LOAD (l);
dfa500
 #endif
dfa500
@@ -1662,17 +1668,6 @@ open_verify (const char *name, int fd,
dfa500
 	  errstring = N_("only ET_DYN and ET_EXEC can be loaded");
dfa500
 	  goto call_lose;
dfa500
 	}
dfa500
-      else if (__glibc_unlikely (ehdr->e_type == ET_EXEC
dfa500
-				 && (mode & __RTLD_OPENEXEC) == 0))
dfa500
-	{
dfa500
-	  /* BZ #16634. It is an error to dlopen ET_EXEC (unless
dfa500
-	     __RTLD_OPENEXEC is explicitly set).  We return error here
dfa500
-	     so that code in _dl_map_object_from_fd does not try to set
dfa500
-	     l_tls_modid for this module.  */
dfa500
-
dfa500
-	  errstring = N_("cannot dynamically load executable");
dfa500
-	  goto call_lose;
dfa500
-	}
dfa500
       else if (__glibc_unlikely (ehdr->e_phentsize != sizeof (ElfW(Phdr))))
dfa500
 	{
dfa500
 	  errstring = N_("ELF file's phentsize not the expected size");