diff mbox series

[v2,1/5] elf: Use RTLD_NODELETE is more places

Message ID 20240731200307.2269811-2-adhemerval.zanella@linaro.org
State New
Headers show
Series Add support for memory sealing | expand

Commit Message

Adhemerval Zanella July 31, 2024, 8:02 p.m. UTC
* On dlopen dependencies for objects opened with RTLD_NODELETE
  (since it does not make sense to unload a dependency of a
   RTLD_NODELETE object);

* For the main map executable.

* For the main map DT_NEEDED dependencies.

* On __libc_unwind_link_get for libgcc_s.so (used for backtrace and
  unwind).

Checked on x86_64-linux-gnu.
---
 elf/dl-open.c      | 3 ++-
 elf/rtld.c         | 6 +++---
 include/dlfcn.h    | 2 ++
 misc/unwind-link.c | 5 +++--
 4 files changed, 10 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/elf/dl-open.c b/elf/dl-open.c
index c378da16c0..076b32b977 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -636,7 +636,8 @@  dl_open_worker_begin (void *a)
 
   /* Load that object's dependencies.  */
   _dl_map_object_deps (new, NULL, 0, 0,
-		       mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT));
+		       mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT
+			       | RTLD_NODELETE));
 
   /* So far, so good.  Now check the versions.  */
   for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
diff --git a/elf/rtld.c b/elf/rtld.c
index bfdf632e77..1090d89bfe 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -811,7 +811,7 @@  do_preload (const char *fname, struct link_map *main_map, const char *where)
 
   args.str = fname;
   args.loader = main_map;
-  args.mode = __RTLD_SECURE;
+  args.mode = __RTLD_SECURE | RTLD_NODELETE;
 
   unsigned int old_nloaded = GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
 
@@ -1638,7 +1638,7 @@  dl_main (const ElfW(Phdr) *phdr,
       /* Create a link_map for the executable itself.
 	 This will be what dlopen on "" returns.  */
       main_map = _dl_new_object ((char *) "", "", lt_executable, NULL,
-				 __RTLD_OPENEXEC, LM_ID_BASE);
+				 __RTLD_OPENEXEC | RTLD_NODELETE, LM_ID_BASE);
       assert (main_map != NULL);
       main_map->l_phdr = phdr;
       main_map->l_phnum = phnum;
@@ -1966,7 +1966,7 @@  dl_main (const ElfW(Phdr) *phdr,
     RTLD_TIMING_VAR (start);
     rtld_timer_start (&start);
     _dl_map_object_deps (main_map, preloads, npreloads,
-			 state.mode == rtld_mode_trace, 0);
+			 state.mode == rtld_mode_trace, RTLD_NODELETE);
     rtld_timer_accum (&load_time, start);
   }
 
diff --git a/include/dlfcn.h b/include/dlfcn.h
index f49ee1b0c9..06e2ecbdd2 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -50,6 +50,8 @@  extern char **__libc_argv attribute_hidden;
    better error handling semantics for the library.  */
 #define __libc_dlopen(name) \
   __libc_dlopen_mode (name, RTLD_NOW | __RTLD_DLOPEN)
+#define __libc_dlopen_nodelete(name) \
+  __libc_dlopen_mode (name, RTLD_NODELETE | RTLD_NOW | __RTLD_DLOPEN)
 extern void *__libc_dlopen_mode  (const char *__name, int __mode)
   attribute_hidden;
 extern void *__libc_dlsym   (void *__map, const char *__name)
diff --git a/misc/unwind-link.c b/misc/unwind-link.c
index 213a0162a4..7267ecbec3 100644
--- a/misc/unwind-link.c
+++ b/misc/unwind-link.c
@@ -48,7 +48,7 @@  __libc_unwind_link_get (void)
   /* Initialize a copy of the data, so that we do not need about
      unlocking in case the dynamic loader somehow triggers
      unwinding.  */
-  void *local_libgcc_handle = __libc_dlopen (LIBGCC_S_SO);
+  void *local_libgcc_handle = __libc_dlopen_nodelete (LIBGCC_S_SO);
   if (local_libgcc_handle == NULL)
     {
       __libc_lock_unlock (lock);
@@ -100,7 +100,8 @@  __libc_unwind_link_get (void)
 
   __libc_lock_lock (lock);
   if (atomic_load_relaxed (&global_libgcc_handle) != NULL)
-    /* This thread lost the race.  Clean up.  */
+    /* This thread lost the race.  Drop the l_direct_opencount and issue
+       the debug log.  */
     __libc_dlclose (local_libgcc_handle);
   else
     {