[RFC 06/11] ima, fs: release namespace policy resources

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Release all namespace IMA policy resources when the mount namespace is
released.
This is the suggested mechanism to release namespace policy resources,
but we still can discuss other methods to avoid cross-component changes.

Signed-off-by: Guilherme Magalhaes <guilherme.magalhaes@xxxxxxx>
---
 fs/namespace.c                  |  4 ++++
 include/linux/integrity.h       |  9 +++++++++
 security/integrity/ima/ima_fs.c | 26 ++++++++++++++++++++++++++
 3 files changed, 39 insertions(+)

diff --git a/fs/namespace.c b/fs/namespace.c
index cc1375ef..80940998 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -15,6 +15,7 @@
 #include <linux/user_namespace.h>
 #include <linux/namei.h>
 #include <linux/security.h>
+#include <linux/integrity.h>
 #include <linux/cred.h>
 #include <linux/idr.h>
 #include <linux/init.h>		/* init_rootfs */
@@ -3283,6 +3284,9 @@ void put_mnt_ns(struct mnt_namespace *ns)
 {
 	if (!atomic_dec_and_test(&ns->count))
 		return;
+
+	ima_mnt_namespace_dying(ns->ns.inum);
+
 	drop_collected_mounts(&ns->root->mnt);
 	free_mnt_ns(ns);
 }
diff --git a/include/linux/integrity.h b/include/linux/integrity.h
index c2d6082..034d082 100644
--- a/include/linux/integrity.h
+++ b/include/linux/integrity.h
@@ -43,4 +43,13 @@ static inline void integrity_load_keys(void)
 }
 #endif /* CONFIG_INTEGRITY */
 
+#ifdef CONFIG_IMA_PER_NAMESPACE
+extern void ima_mnt_namespace_dying(unsigned int ns_id);
+#else
+static inline void ima_mnt_namespace_dying(unsigned int ns_id)
+{
+	return;
+}
+#endif /* CONFIG_IMA_PER_NAMESPACE */
+
 #endif /* _LINUX_INTEGRITY_H */
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index ce6dcdf..56ba0ff 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -423,6 +423,7 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
 		integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
 				    "policy_update", "signed policy required",
 				    1, 0);
+
 		if (ima_appraise & IMA_APPRAISE_ENFORCE)
 			result = -EACCES;
 	} else {
@@ -579,6 +580,31 @@ static int create_mnt_ns_directory(unsigned int ns_id)
 	return result;
 }
 
+/*
+ * ima_mnt_namespace_dying - releases all namespace policy resources
+ * It is called automatically when the namespace is released.
+ * @ns_id namespace id to be released
+ *
+ * Note: This function is called by put_mnt_ns() in the context
+ * of a namespace release. We need to make sure that a lock on
+ * this path is allowed.
+ */
+void ima_mnt_namespace_dying(unsigned int ns_id)
+{
+	struct ima_ns_policy *p;
+
+	spin_lock(&ima_ns_policy_lock);
+	p = radix_tree_delete(&ima_ns_policy_mapping, ns_id);
+
+	if (!p) {
+		spin_unlock(&ima_ns_policy_lock);
+		return;
+	}
+
+	free_namespace_policy(p);
+	spin_unlock(&ima_ns_policy_lock);
+}
+
 static ssize_t handle_new_namespace_policy(const char *data, size_t datalen)
 {
 	unsigned int ns_id;
-- 
2.7.4




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux