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