4c1956
commit 3dac3959a5cb585b065cef2cb8a8d909c907e202
4c1956
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
4c1956
Date:   Tue Jul 20 11:03:34 2021 -0300
4c1956
4c1956
    elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid
4c1956
    
4c1956
    It consolidates the code required to call la_activity audit
4c1956
    callback.
4c1956
    
4c1956
    Also for a new Lmid_t the namespace link_map list are empty, so it
4c1956
    requires to check if before using it.  This can happen for when audit
4c1956
    module is used along with dlmopen.
4c1956
    
4c1956
    Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
4c1956
    
4c1956
    Reviewed-by: Florian Weimer <fweimer@redhat.com>
4c1956
4c1956
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
4c1956
index 4066dfe85146b9d4..74b87f4b39be75e1 100644
4c1956
--- a/elf/dl-audit.c
4c1956
+++ b/elf/dl-audit.c
4c1956
@@ -18,6 +18,32 @@
4c1956
 
4c1956
 #include <ldsodefs.h>
4c1956
 
4c1956
+void
4c1956
+_dl_audit_activity_map (struct link_map *l, int action)
4c1956
+{
4c1956
+  struct audit_ifaces *afct = GLRO(dl_audit);
4c1956
+  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
4c1956
+    {
4c1956
+      if (afct->activity != NULL)
4c1956
+	afct->activity (&link_map_audit_state (l, cnt)->cookie, action);
4c1956
+      afct = afct->next;
4c1956
+    }
4c1956
+}
4c1956
+
4c1956
+void
4c1956
+_dl_audit_activity_nsid (Lmid_t nsid, int action)
4c1956
+{
4c1956
+  /* If head is NULL, the namespace has become empty, and the audit interface
4c1956
+     does not give us a way to signal LA_ACT_CONSISTENT for it because the
4c1956
+     first loaded module is used to identify the namespace.  */
4c1956
+  struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
4c1956
+  if (__glibc_likely (GLRO(dl_naudit) == 0)
4c1956
+      || head == NULL || head->l_auditing)
4c1956
+    return;
4c1956
+
4c1956
+  _dl_audit_activity_map (head, action);
4c1956
+}
4c1956
+
4c1956
 void
4c1956
 _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
4c1956
 {
4c1956
diff --git a/elf/dl-close.c b/elf/dl-close.c
4c1956
index 698bda929c0eab6c..1ba594b600c4c87a 100644
4c1956
--- a/elf/dl-close.c
4c1956
+++ b/elf/dl-close.c
4c1956
@@ -478,25 +478,7 @@ _dl_close_worker (struct link_map *map, bool force)
4c1956
 
4c1956
 #ifdef SHARED
4c1956
   /* Auditing checkpoint: we will start deleting objects.  */
4c1956
-  if (__glibc_unlikely (do_audit))
4c1956
-    {
4c1956
-      struct link_map *head = ns->_ns_loaded;
4c1956
-      struct audit_ifaces *afct = GLRO(dl_audit);
4c1956
-      /* Do not call the functions for any auditing object.  */
4c1956
-      if (head->l_auditing == 0)
4c1956
-	{
4c1956
-	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
4c1956
-	    {
4c1956
-	      if (afct->activity != NULL)
4c1956
-		{
4c1956
-		  struct auditstate *state = link_map_audit_state (head, cnt);
4c1956
-		  afct->activity (&state->cookie, LA_ACT_DELETE);
4c1956
-		}
4c1956
-
4c1956
-	      afct = afct->next;
4c1956
-	    }
4c1956
-	}
4c1956
-    }
4c1956
+  _dl_audit_activity_nsid (nsid, LA_ACT_DELETE);
4c1956
 #endif
4c1956
 
4c1956
   /* Notify the debugger we are about to remove some loaded objects.  */
4c1956
@@ -791,32 +773,9 @@ _dl_close_worker (struct link_map *map, bool force)
4c1956
   __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
4c1956
 
4c1956
 #ifdef SHARED
4c1956
-  /* Auditing checkpoint: we have deleted all objects.  */
4c1956
-  if (__glibc_unlikely (do_audit))
4c1956
-    {
4c1956
-      struct link_map *head = ns->_ns_loaded;
4c1956
-      /* If head is NULL, the namespace has become empty, and the
4c1956
-	 audit interface does not give us a way to signal
4c1956
-	 LA_ACT_CONSISTENT for it because the first loaded module is
4c1956
-	 used to identify the namespace.
4c1956
-
4c1956
-	 Furthermore, do not notify auditors of the cleanup of a
4c1956
-	 failed audit module loading attempt.  */
4c1956
-      if (head != NULL && head->l_auditing == 0)
4c1956
-	{
4c1956
-	  struct audit_ifaces *afct = GLRO(dl_audit);
4c1956
-	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
4c1956
-	    {
4c1956
-	      if (afct->activity != NULL)
4c1956
-		{
4c1956
-		  struct auditstate *state = link_map_audit_state (head, cnt);
4c1956
-		  afct->activity (&state->cookie, LA_ACT_CONSISTENT);
4c1956
-		}
4c1956
-
4c1956
-	      afct = afct->next;
4c1956
-	    }
4c1956
-	}
4c1956
-    }
4c1956
+  /* Auditing checkpoint: we have deleted all objects.  Also, do not notify
4c1956
+     auditors of the cleanup of a failed audit module loading attempt.  */
4c1956
+  _dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT);
4c1956
 #endif
4c1956
 
4c1956
   if (__builtin_expect (ns->_ns_loaded == NULL, 0)
4c1956
diff --git a/elf/dl-load.c b/elf/dl-load.c
4c1956
index c11b1d1781e9b40b..8a18c761bb753e37 100644
4c1956
--- a/elf/dl-load.c
4c1956
+++ b/elf/dl-load.c
4c1956
@@ -1403,24 +1403,8 @@ cannot enable executable stack as shared object requires");
4c1956
       /* Auditing checkpoint: we are going to add new objects.  Since this
4c1956
          is called after _dl_add_to_namespace_list the namespace is guaranteed
4c1956
 	 to not be empty.  */
4c1956
-      if ((mode & __RTLD_AUDIT) == 0
4c1956
-	  && __glibc_unlikely (GLRO(dl_naudit) > 0))
4c1956
-	{
4c1956
-	  struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
4c1956
-	  /* Do not call the functions for any auditing object.  */
4c1956
-	  if (head->l_auditing == 0)
4c1956
-	    {
4c1956
-	      struct audit_ifaces *afct = GLRO(dl_audit);
4c1956
-	      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
4c1956
-		{
4c1956
-		  if (afct->activity != NULL)
4c1956
-		    afct->activity (&link_map_audit_state (head, cnt)->cookie,
4c1956
-				    LA_ACT_ADD);
4c1956
-
4c1956
-		  afct = afct->next;
4c1956
-		}
4c1956
-	    }
4c1956
-	}
4c1956
+      if ((mode & __RTLD_AUDIT) == 0)
4c1956
+	_dl_audit_activity_nsid (nsid, LA_ACT_ADD);
4c1956
 #endif
4c1956
 
4c1956
       /* Notify the debugger we have added some objects.  We need to
4c1956
diff --git a/elf/dl-open.c b/elf/dl-open.c
4c1956
index b5a4da04907d8d29..660a56b2fb2639cd 100644
4c1956
--- a/elf/dl-open.c
4c1956
+++ b/elf/dl-open.c
4c1956
@@ -598,25 +598,7 @@ dl_open_worker_begin (void *a)
4c1956
 
4c1956
 #ifdef SHARED
4c1956
   /* Auditing checkpoint: we have added all objects.  */
4c1956
-  if (__glibc_unlikely (GLRO(dl_naudit) > 0))
4c1956
-    {
4c1956
-      struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded;
4c1956
-      /* Do not call the functions for any auditing object.  */
4c1956
-      if (head->l_auditing == 0)
4c1956
-	{
4c1956
-	  struct audit_ifaces *afct = GLRO(dl_audit);
4c1956
-	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
4c1956
-	    {
4c1956
-	      if (afct->activity != NULL)
4c1956
-		{
4c1956
-		  struct auditstate *state = link_map_audit_state (head, cnt);
4c1956
-		  afct->activity (&state->cookie, LA_ACT_CONSISTENT);
4c1956
-		}
4c1956
-
4c1956
-	      afct = afct->next;
4c1956
-	    }
4c1956
-	}
4c1956
-    }
4c1956
+  _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT);
4c1956
 #endif
4c1956
 
4c1956
   /* Notify the debugger all new objects are now ready to go.  */
4c1956
diff --git a/elf/rtld.c b/elf/rtld.c
4c1956
index 1982e42390760e0a..767acd122262b824 100644
4c1956
--- a/elf/rtld.c
4c1956
+++ b/elf/rtld.c
4c1956
@@ -1799,18 +1799,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
4c1956
 
4c1956
   /* Auditing checkpoint: we are ready to signal that the initial map
4c1956
      is being constructed.  */
4c1956
-  if (__glibc_unlikely (GLRO(dl_naudit) > 0))
4c1956
-    {
4c1956
-      struct audit_ifaces *afct = GLRO(dl_audit);
4c1956
-      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
4c1956
-	{
4c1956
-	  if (afct->activity != NULL)
4c1956
-	    afct->activity (&link_map_audit_state (main_map, cnt)->cookie,
4c1956
-			    LA_ACT_ADD);
4c1956
-
4c1956
-	  afct = afct->next;
4c1956
-	}
4c1956
-    }
4c1956
+  _dl_audit_activity_map (main_map, LA_ACT_ADD);
4c1956
 
4c1956
   /* We have two ways to specify objects to preload: via environment
4c1956
      variable and via the file /etc/ld.so.preload.  The latter can also
4c1956
@@ -2484,23 +2473,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
4c1956
 
4c1956
 #ifdef SHARED
4c1956
   /* Auditing checkpoint: we have added all objects.  */
4c1956
-  if (__glibc_unlikely (GLRO(dl_naudit) > 0))
4c1956
-    {
4c1956
-      struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
4c1956
-      /* Do not call the functions for any auditing object.  */
4c1956
-      if (head->l_auditing == 0)
4c1956
-	{
4c1956
-	  struct audit_ifaces *afct = GLRO(dl_audit);
4c1956
-	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
4c1956
-	    {
4c1956
-	      if (afct->activity != NULL)
4c1956
-		afct->activity (&link_map_audit_state (head, cnt)->cookie,
4c1956
-				LA_ACT_CONSISTENT);
4c1956
-
4c1956
-	      afct = afct->next;
4c1956
-	    }
4c1956
-	}
4c1956
-    }
4c1956
+  _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT);
4c1956
 #endif
4c1956
 
4c1956
   /* Notify the debugger all new objects are now ready to go.  We must re-get
4c1956
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
4c1956
index 410f070e28b74bdf..05737342d6287233 100644
4c1956
--- a/sysdeps/generic/ldsodefs.h
4c1956
+++ b/sysdeps/generic/ldsodefs.h
4c1956
@@ -1269,6 +1269,16 @@ link_map_audit_state (struct link_map *l, size_t index)
4c1956
   return &l->l_audit[index];
4c1956
 }
4c1956
 
4c1956
+/* Call the la_activity from the audit modules from the link map L and issues
4c1956
+   the ACTION argument.  */
4c1956
+void _dl_audit_activity_map (struct link_map *l, int action)
4c1956
+  attribute_hidden;
4c1956
+
4c1956
+/* Call the la_activity from the audit modules from the link map from the
4c1956
+   namespace NSID and issues the ACTION argument.  */
4c1956
+void _dl_audit_activity_nsid (Lmid_t nsid, int action)
4c1956
+  attribute_hidden;
4c1956
+
4c1956
 /* Call the la_objopen from the audit modules for the link_map L on the
4c1956
    namespace identification NSID.  */
4c1956
 void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)