lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 10 Jan 2024 16:48:50 +0530
From: Neeraj Upadhyay <Neeraj.Upadhyay@....com>
To: <john.johansen@...onical.com>, <paul@...l-moore.com>, <jmorris@...ei.org>,
	<serge@...lyn.com>
CC: <linux-security-module@...r.kernel.org>, <apparmor@...ts.ubuntu.com>,
	<linux-kernel@...r.kernel.org>, <gautham.shenoy@....com>,
	<Santosh.Shukla@....com>, <Ananth.Narayan@....com>,
	<raghavendra.kodsarathimmappa@....com>, <paulmck@...nel.org>,
	<boqun.feng@...il.com>, <vinicius.gomes@...el.com>, <mjguzik@...il.com>,
	Neeraj Upadhyay <Neeraj.Upadhyay@....com>
Subject: [RFC 3/9] apparmor: Switch unconfined namespaces refcount to percpu mode

Switch unconfined labels to percpu mode, to avoid high
memory contention on refcount get and put operations,
when multiple cpus try to perform these operations
at the same time. Unconfined label for root and sub
namespaces are killed at the point of aa_free_root_ns().
Though labels/profiles in various namespaces could
potentially still be active after this point, aa_free_root_ns()
is not typically called when apparmor enforcement is enabled.

Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@....com>
---
 security/apparmor/include/policy.h    | 24 ++++++++++++++++++++++++
 security/apparmor/include/policy_ns.h | 24 ++++++++++++++++++++++++
 security/apparmor/policy_ns.c         |  6 ++++--
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 5849b6b94cea..1e3b29ba6c03 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -379,6 +379,30 @@ static inline void aa_put_profile(struct aa_profile *p)
 		percpu_ref_put(&p->label.count);
 }
 
+/**
+ * aa_switch_ref_profile - switch percpu-ref mode for profile @p
+ * @p: profile  (MAYBE NULL)
+ */
+static inline void aa_switch_ref_profile(struct aa_profile *p, bool percpu)
+{
+	if (p) {
+		if (percpu)
+			percpu_ref_switch_to_percpu(&p->label.count);
+		else
+			percpu_ref_switch_to_atomic_sync(&p->label.count);
+	}
+}
+
+/**
+ * aa_kill_ref_profile - percpu-ref kill for profile @p
+ * @p: profile  (MAYBE NULL)
+ */
+static inline void aa_kill_ref_profile(struct aa_profile *p)
+{
+	if (p)
+		percpu_ref_kill(&p->label.count);
+}
+
 static inline int AUDIT_MODE(struct aa_profile *profile)
 {
 	if (aa_g_audit != AUDIT_NORMAL)
diff --git a/security/apparmor/include/policy_ns.h b/security/apparmor/include/policy_ns.h
index d646070fd966..f3db01c5e193 100644
--- a/security/apparmor/include/policy_ns.h
+++ b/security/apparmor/include/policy_ns.h
@@ -127,6 +127,30 @@ static inline void aa_put_ns(struct aa_ns *ns)
 		aa_put_profile(ns->unconfined);
 }
 
+/**
+ * aa_switch_ref_ns - switch percpu-ref mode for @ns
+ * @ns: namespace to switch percpu-ref mode of
+ *
+ * Switch percpu-ref mode of @ns between percpu and atomic
+ */
+static inline void aa_switch_ref_ns(struct aa_ns *ns, bool percpu)
+{
+	if (ns)
+		aa_switch_ref_profile(ns->unconfined, percpu);
+}
+
+/**
+ * aa_kill_ref_ns - do percpu-ref kill for @ns
+ * @ns: namespace to perform percpu-ref kill for
+ *
+ * Do percpu-ref kill of @ns refcount
+ */
+static inline void aa_kill_ref_ns(struct aa_ns *ns)
+{
+	if (ns)
+		aa_kill_ref_profile(ns->unconfined);
+}
+
 /**
  * __aa_findn_ns - find a namespace on a list by @name
  * @head: list to search for namespace on  (NOT NULL)
diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
index 1f02cfe1d974..ca633cfbd936 100644
--- a/security/apparmor/policy_ns.c
+++ b/security/apparmor/policy_ns.c
@@ -124,6 +124,7 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
 		goto fail_unconfined;
 	/* ns and ns->unconfined share ns->unconfined refcount */
 	ns->unconfined->ns = ns;
+	aa_switch_ref_ns(ns, true);
 
 	atomic_set(&ns->uniq_null, 0);
 
@@ -336,7 +337,7 @@ void __aa_remove_ns(struct aa_ns *ns)
 	/* remove ns from namespace list */
 	list_del_rcu(&ns->base.list);
 	destroy_ns(ns);
-	aa_put_ns(ns);
+	aa_kill_ref_ns(ns);
 }
 
 /**
@@ -377,6 +378,7 @@ int __init aa_alloc_root_ns(void)
 	}
 	kernel_t = &kernel_p->label;
 	root_ns->unconfined->ns = aa_get_ns(root_ns);
+	aa_switch_ref_ns(root_ns, true);
 
 	return 0;
 }
@@ -392,5 +394,5 @@ void __init aa_free_root_ns(void)
 
 	 aa_label_free(kernel_t);
 	 destroy_ns(ns);
-	 aa_put_ns(ns);
+	 aa_kill_ref_ns(ns);
 }
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ