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