076f82
commit 66e9d27a090874ab93030a908eb86fc29f856151
076f82
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
076f82
Date:   Tue Jul 20 11:03:34 2021 -0300
076f82
076f82
    elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid
076f82
    
076f82
    It consolidates the code required to call la_activity audit
076f82
    callback.
076f82
    
076f82
    Also for a new Lmid_t the namespace link_map list are empty, so it
076f82
    requires to check if before using it.  This can happen for when audit
076f82
    module is used along with dlmopen.
076f82
    
076f82
    Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
076f82
    
076f82
    Reviewed-by: Florian Weimer <fweimer@redhat.com>
076f82
    (cherry picked from commit 3dac3959a5cb585b065cef2cb8a8d909c907e202)
076f82
076f82
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
076f82
index 4066dfe85146b9d4..74b87f4b39be75e1 100644
076f82
--- a/elf/dl-audit.c
076f82
+++ b/elf/dl-audit.c
076f82
@@ -18,6 +18,32 @@
076f82
 
076f82
 #include <ldsodefs.h>
076f82
 
076f82
+void
076f82
+_dl_audit_activity_map (struct link_map *l, int action)
076f82
+{
076f82
+  struct audit_ifaces *afct = GLRO(dl_audit);
076f82
+  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
076f82
+    {
076f82
+      if (afct->activity != NULL)
076f82
+	afct->activity (&link_map_audit_state (l, cnt)->cookie, action);
076f82
+      afct = afct->next;
076f82
+    }
076f82
+}
076f82
+
076f82
+void
076f82
+_dl_audit_activity_nsid (Lmid_t nsid, int action)
076f82
+{
076f82
+  /* If head is NULL, the namespace has become empty, and the audit interface
076f82
+     does not give us a way to signal LA_ACT_CONSISTENT for it because the
076f82
+     first loaded module is used to identify the namespace.  */
076f82
+  struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
076f82
+  if (__glibc_likely (GLRO(dl_naudit) == 0)
076f82
+      || head == NULL || head->l_auditing)
076f82
+    return;
076f82
+
076f82
+  _dl_audit_activity_map (head, action);
076f82
+}
076f82
+
076f82
 void
076f82
 _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
076f82
 {
076f82
diff --git a/elf/dl-close.c b/elf/dl-close.c
076f82
index f6fbf9de7d78555b..5a8cc9e7cb5186cc 100644
076f82
--- a/elf/dl-close.c
076f82
+++ b/elf/dl-close.c
076f82
@@ -472,25 +472,7 @@ _dl_close_worker (struct link_map *map, bool force)
076f82
 
076f82
 #ifdef SHARED
076f82
   /* Auditing checkpoint: we will start deleting objects.  */
076f82
-  if (__glibc_unlikely (do_audit))
076f82
-    {
076f82
-      struct link_map *head = ns->_ns_loaded;
076f82
-      struct audit_ifaces *afct = GLRO(dl_audit);
076f82
-      /* Do not call the functions for any auditing object.  */
076f82
-      if (head->l_auditing == 0)
076f82
-	{
076f82
-	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
076f82
-	    {
076f82
-	      if (afct->activity != NULL)
076f82
-		{
076f82
-		  struct auditstate *state = link_map_audit_state (head, cnt);
076f82
-		  afct->activity (&state->cookie, LA_ACT_DELETE);
076f82
-		}
076f82
-
076f82
-	      afct = afct->next;
076f82
-	    }
076f82
-	}
076f82
-    }
076f82
+  _dl_audit_activity_nsid (nsid, LA_ACT_DELETE);
076f82
 #endif
076f82
 
076f82
   /* Notify the debugger we are about to remove some loaded objects.  */
076f82
@@ -785,32 +767,9 @@ _dl_close_worker (struct link_map *map, bool force)
076f82
   __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
076f82
 
076f82
 #ifdef SHARED
076f82
-  /* Auditing checkpoint: we have deleted all objects.  */
076f82
-  if (__glibc_unlikely (do_audit))
076f82
-    {
076f82
-      struct link_map *head = ns->_ns_loaded;
076f82
-      /* If head is NULL, the namespace has become empty, and the
076f82
-	 audit interface does not give us a way to signal
076f82
-	 LA_ACT_CONSISTENT for it because the first loaded module is
076f82
-	 used to identify the namespace.
076f82
-
076f82
-	 Furthermore, do not notify auditors of the cleanup of a
076f82
-	 failed audit module loading attempt.  */
076f82
-      if (head != NULL && head->l_auditing == 0)
076f82
-	{
076f82
-	  struct audit_ifaces *afct = GLRO(dl_audit);
076f82
-	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
076f82
-	    {
076f82
-	      if (afct->activity != NULL)
076f82
-		{
076f82
-		  struct auditstate *state = link_map_audit_state (head, cnt);
076f82
-		  afct->activity (&state->cookie, LA_ACT_CONSISTENT);
076f82
-		}
076f82
-
076f82
-	      afct = afct->next;
076f82
-	    }
076f82
-	}
076f82
-    }
076f82
+  /* Auditing checkpoint: we have deleted all objects.  Also, do not notify
076f82
+     auditors of the cleanup of a failed audit module loading attempt.  */
076f82
+  _dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT);
076f82
 #endif
076f82
 
076f82
   if (__builtin_expect (ns->_ns_loaded == NULL, 0)
076f82
diff --git a/elf/dl-load.c b/elf/dl-load.c
076f82
index a2d73d025c65cd79..baf0a926053deaed 100644
076f82
--- a/elf/dl-load.c
076f82
+++ b/elf/dl-load.c
076f82
@@ -1482,24 +1482,8 @@ cannot enable executable stack as shared object requires");
076f82
       /* Auditing checkpoint: we are going to add new objects.  Since this
076f82
          is called after _dl_add_to_namespace_list the namespace is guaranteed
076f82
 	 to not be empty.  */
076f82
-      if ((mode & __RTLD_AUDIT) == 0
076f82
-	  && __glibc_unlikely (GLRO(dl_naudit) > 0))
076f82
-	{
076f82
-	  struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
076f82
-	  /* Do not call the functions for any auditing object.  */
076f82
-	  if (head->l_auditing == 0)
076f82
-	    {
076f82
-	      struct audit_ifaces *afct = GLRO(dl_audit);
076f82
-	      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
076f82
-		{
076f82
-		  if (afct->activity != NULL)
076f82
-		    afct->activity (&link_map_audit_state (head, cnt)->cookie,
076f82
-				    LA_ACT_ADD);
076f82
-
076f82
-		  afct = afct->next;
076f82
-		}
076f82
-	    }
076f82
-	}
076f82
+      if ((mode & __RTLD_AUDIT) == 0)
076f82
+	_dl_audit_activity_nsid (nsid, LA_ACT_ADD);
076f82
 #endif
076f82
 
076f82
       /* Notify the debugger we have added some objects.  We need to
076f82
diff --git a/elf/dl-open.c b/elf/dl-open.c
076f82
index bc68e2c376debd71..3f01aa480730da13 100644
076f82
--- a/elf/dl-open.c
076f82
+++ b/elf/dl-open.c
076f82
@@ -611,25 +611,7 @@ dl_open_worker_begin (void *a)
076f82
 
076f82
 #ifdef SHARED
076f82
   /* Auditing checkpoint: we have added all objects.  */
076f82
-  if (__glibc_unlikely (GLRO(dl_naudit) > 0))
076f82
-    {
076f82
-      struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded;
076f82
-      /* Do not call the functions for any auditing object.  */
076f82
-      if (head->l_auditing == 0)
076f82
-	{
076f82
-	  struct audit_ifaces *afct = GLRO(dl_audit);
076f82
-	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
076f82
-	    {
076f82
-	      if (afct->activity != NULL)
076f82
-		{
076f82
-		  struct auditstate *state = link_map_audit_state (head, cnt);
076f82
-		  afct->activity (&state->cookie, LA_ACT_CONSISTENT);
076f82
-		}
076f82
-
076f82
-	      afct = afct->next;
076f82
-	    }
076f82
-	}
076f82
-    }
076f82
+  _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT);
076f82
 #endif
076f82
 
076f82
   /* Notify the debugger all new objects are now ready to go.  */
076f82
diff --git a/elf/rtld.c b/elf/rtld.c
076f82
index 45fec0df3043b90a..b6bb46ca97b7972f 100644
076f82
--- a/elf/rtld.c
076f82
+++ b/elf/rtld.c
076f82
@@ -1804,18 +1804,7 @@ dl_main (const ElfW(Phdr) *phdr,
076f82
 
076f82
   /* Auditing checkpoint: we are ready to signal that the initial map
076f82
      is being constructed.  */
076f82
-  if (__glibc_unlikely (GLRO(dl_naudit) > 0))
076f82
-    {
076f82
-      struct audit_ifaces *afct = GLRO(dl_audit);
076f82
-      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
076f82
-	{
076f82
-	  if (afct->activity != NULL)
076f82
-	    afct->activity (&link_map_audit_state (main_map, cnt)->cookie,
076f82
-			    LA_ACT_ADD);
076f82
-
076f82
-	  afct = afct->next;
076f82
-	}
076f82
-    }
076f82
+  _dl_audit_activity_map (main_map, LA_ACT_ADD);
076f82
 
076f82
   /* We have two ways to specify objects to preload: via environment
076f82
      variable and via the file /etc/ld.so.preload.  The latter can also
076f82
@@ -2496,23 +2485,7 @@ dl_main (const ElfW(Phdr) *phdr,
076f82
 
076f82
 #ifdef SHARED
076f82
   /* Auditing checkpoint: we have added all objects.  */
076f82
-  if (__glibc_unlikely (GLRO(dl_naudit) > 0))
076f82
-    {
076f82
-      struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
076f82
-      /* Do not call the functions for any auditing object.  */
076f82
-      if (head->l_auditing == 0)
076f82
-	{
076f82
-	  struct audit_ifaces *afct = GLRO(dl_audit);
076f82
-	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
076f82
-	    {
076f82
-	      if (afct->activity != NULL)
076f82
-		afct->activity (&link_map_audit_state (head, cnt)->cookie,
076f82
-				LA_ACT_CONSISTENT);
076f82
-
076f82
-	      afct = afct->next;
076f82
-	    }
076f82
-	}
076f82
-    }
076f82
+  _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT);
076f82
 #endif
076f82
 
076f82
   /* Notify the debugger all new objects are now ready to go.  We must re-get
076f82
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
076f82
index 5709e4e48dff4355..7384abcf5e0e8e24 100644
076f82
--- a/sysdeps/generic/ldsodefs.h
076f82
+++ b/sysdeps/generic/ldsodefs.h
076f82
@@ -1373,6 +1373,16 @@ link_map_audit_state (struct link_map *l, size_t index)
076f82
     }
076f82
 }
076f82
 
076f82
+/* Call the la_activity from the audit modules from the link map L and issues
076f82
+   the ACTION argument.  */
076f82
+void _dl_audit_activity_map (struct link_map *l, int action)
076f82
+  attribute_hidden;
076f82
+
076f82
+/* Call the la_activity from the audit modules from the link map from the
076f82
+   namespace NSID and issues the ACTION argument.  */
076f82
+void _dl_audit_activity_nsid (Lmid_t nsid, int action)
076f82
+  attribute_hidden;
076f82
+
076f82
 /* Call the la_objopen from the audit modules for the link_map L on the
076f82
    namespace identification NSID.  */
076f82
 void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)