diff mbox series

[v2,2/3] elf: Signal LA_ACT_CONSISTENT to auditors after RT_CONSISTENT switch

Message ID 3238d4cc26934a86acd8b8f3e01a6dcc33ab798e.1723116962.git.fweimer@redhat.com
State New
Headers show
Series Fixes for recursive dlopen (bug 31986) | expand

Commit Message

Florian Weimer Aug. 8, 2024, 11:40 a.m. UTC
Auditors can call into the dynamic loader again if
LA_ACT_CONSISTENT, and  those recursive calls could observe
r_state != RT_CONSISTENT.

We should consider failing dlopen/dlmopen/dlclose if
r_state != RT_CONSISTENT.  The dynamic linker is probably not
in a state in which it can handle reentrant calls.  This
needs further investigation.
---
 elf/dl-close.c | 10 +++++-----
 elf/dl-open.c  | 10 +++++-----
 elf/rtld.c     |  6 +++---
 3 files changed, 13 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/elf/dl-close.c b/elf/dl-close.c
index 88226245eb..b6f4daac79 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -723,6 +723,11 @@  _dl_close_worker (struct link_map *map, bool force)
   /* TLS is cleaned up for the unloaded modules.  */
   __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
 
+  /* Notify the debugger those objects are finalized and gone.  */
+  r->r_state = RT_CONSISTENT;
+  _dl_debug_state ();
+  LIBC_PROBE (unmap_complete, 2, nsid, r);
+
 #ifdef SHARED
   /* Auditing checkpoint: we have deleted all objects.  Also, do not notify
      auditors of the cleanup of a failed audit module loading attempt.  */
@@ -735,11 +740,6 @@  _dl_close_worker (struct link_map *map, bool force)
       --GL(dl_nns);
     while (GL(dl_ns)[GL(dl_nns) - 1]._ns_loaded == NULL);
 
-  /* Notify the debugger those objects are finalized and gone.  */
-  r->r_state = RT_CONSISTENT;
-  _dl_debug_state ();
-  LIBC_PROBE (unmap_complete, 2, nsid, r);
-
   /* Recheck if we need to retry, release the lock.  */
  out:
   if (dl_close_state == rerun)
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 2c20aa1df9..5e74807d23 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -628,17 +628,17 @@  dl_open_worker_begin (void *a)
 #endif
       }
 
-#ifdef SHARED
-  /* Auditing checkpoint: we have added all objects.  */
-  _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT);
-#endif
-
   /* Notify the debugger all new objects are now ready to go.  */
   struct r_debug *r = _dl_debug_update (args->nsid);
   r->r_state = RT_CONSISTENT;
   _dl_debug_state ();
   LIBC_PROBE (map_complete, 3, args->nsid, r, new);
 
+#ifdef SHARED
+  /* Auditing checkpoint: we have added all objects.  */
+  _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT);
+#endif
+
   _dl_open_check (new);
 
   /* Print scope information.  */
diff --git a/elf/rtld.c b/elf/rtld.c
index 1e2e9ad5a8..0dd64de13a 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2393,9 +2393,6 @@  dl_main (const ElfW(Phdr) *phdr,
      _dl_relocate_object might need to call `mprotect' for DT_TEXTREL.  */
   _dl_sysdep_start_cleanup ();
 
-  /* Auditing checkpoint: we have added all objects.  */
-  _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT);
-
   /* Notify the debugger all new objects are now ready to go.  We must re-get
      the address since by now the variable might be in another object.  */
   r = _dl_debug_update (LM_ID_BASE);
@@ -2403,6 +2400,9 @@  dl_main (const ElfW(Phdr) *phdr,
   _dl_debug_state ();
   LIBC_PROBE (init_complete, 2, LM_ID_BASE, r);
 
+  /* Auditing checkpoint: we have added all objects.  */
+  _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT);
+
 #if defined USE_LDCONFIG && !defined MAP_COPY
   /* We must munmap() the cache file.  */
   _dl_unload_cache ();