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