diff --git a/include/linux/ima.h b/include/linux/ima.h
index 4a9c29d4d056..5b6235b97603 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -10,10 +10,12 @@
 #include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/kexec.h>
-struct linux_binprm;
 
+struct linux_binprm;
 struct nsproxy;
 struct task_struct;
+struct list_head;
+struct llist_node;
 
 #ifdef CONFIG_IMA
 extern int ima_bprm_check(struct linux_binprm *bprm);
@@ -176,6 +178,10 @@ struct ima_namespace {
 	struct ns_common ns;
 	struct ucounts *ucounts;
 	struct user_namespace *user_ns;
+	struct list_head list;
+	struct llist_node cleanup_list; /* namespaces on a death row */
+	atomic_t inactive; /* set only when ns is added to the cleanup list */
+	bool frozen;
 } __randomize_layout;
 
 extern struct ima_namespace init_ima_ns;
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 603da5b2db08..092e87190c6d 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -372,12 +372,23 @@ static inline int ima_read_xattr(struct dentry *dentry,
 
 #endif /* CONFIG_IMA_APPRAISE */
 
+extern struct list_head ima_ns_list;
+extern struct rw_semaphore ima_ns_list_lock;
+
 #ifdef CONFIG_IMA_NS
+int __init ima_init_namespace(void);
+
 static inline struct ima_namespace *get_current_ns(void)
 {
 	return current->nsproxy->ima_ns;
 }
 #else
+static inline int __init ima_init_namespace(void)
+{
+	list_add_tail(&init_ima_ns.list, &ima_ns_list);
+	return 0;
+}
+
 static inline struct ima_namespace *get_current_ns(void)
 {
 	return &init_ima_ns;
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 013bbec16849..0ba04a1a68cc 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -32,6 +32,7 @@ struct ima_namespace init_ima_ns = {
 #ifdef CONFIG_IMA_NS
 	.ns.ops = &imans_operations,
 #endif
+	.frozen = true
 };
 EXPORT_SYMBOL(init_ima_ns);
 
@@ -154,6 +155,10 @@ int __init ima_init(void)
 
 	ima_init_policy();
 
+	rc = ima_init_namespace();
+	if (rc != 0)
+		return rc;
+
 	rc = ima_fs_init();
 	if (rc != 0)
 		return rc;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 8a91711ca79b..d800e73c8b62 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -37,6 +37,9 @@ int ima_appraise;
 int ima_hash_algo = HASH_ALGO_SHA1;
 static int hash_setup_done;
 
+DECLARE_RWSEM(ima_ns_list_lock);
+LIST_HEAD(ima_ns_list);
+
 static struct notifier_block ima_lsm_policy_notifier = {
 	.notifier_call = ima_lsm_policy_change,
 };
diff --git a/security/integrity/ima/ima_ns.c b/security/integrity/ima/ima_ns.c
index 8f5f301406a2..3a98cd536d05 100644
--- a/security/integrity/ima/ima_ns.c
+++ b/security/integrity/ima/ima_ns.c
@@ -21,9 +21,20 @@
 #include <linux/user_namespace.h>
 #include <linux/nsproxy.h>
 #include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/llist.h>
+#include <linux/rwsem.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
 
 #include "ima.h"
 
+static LLIST_HEAD(cleanup_list);
+static struct workqueue_struct *imans_wq;
+
+/* Protects tasks entering the same, not yet active namespace */
+static DEFINE_MUTEX(frozen_lock);
+
 static struct ucounts *inc_ima_namespaces(struct user_namespace *ns)
 {
 	return inc_ucount(ns, current_euid(), UCOUNT_IMA_NAMESPACES);
@@ -78,6 +89,7 @@ static struct ima_namespace *clone_ima_ns(struct user_namespace *user_ns,
 	ns->ns.ops = &imans_operations;
 	ns->user_ns = get_user_ns(user_ns);
 	ns->ucounts = ucounts;
+	ns->frozen = false;
 
 	return ns;
 
@@ -109,6 +121,19 @@ struct ima_namespace *copy_ima_ns(unsigned long flags,
 	return clone_ima_ns(user_ns, old_ns);
 }
 
+int __init ima_init_namespace(void)
+{
+	/* Create workqueue for cleanup */
+	imans_wq = create_singlethread_workqueue("imans");
+	if (unlikely(!imans_wq))
+		return -ENOMEM;
+
+	/* No other reader or writer at this stage */
+	list_add_tail(&init_ima_ns.list, &ima_ns_list);
+
+	return 0;
+}
+
 static void destroy_ima_ns(struct ima_namespace *ns)
 {
 	dec_ima_namespaces(ns->ucounts);
@@ -117,13 +142,46 @@ static void destroy_ima_ns(struct ima_namespace *ns)
 	kfree(ns);
 }
 
+static void cleanup_ima(struct work_struct *work)
+{
+	struct ima_namespace *ima_ns, *tmp;
+	struct llist_node *ima_kill_list;
+
+	/* Atomically snapshot the list of namespaces to cleanup */
+	ima_kill_list = llist_del_all(&cleanup_list);
+
+	/* Remove ima namespace from the namespace list */
+	down_write(&ima_ns_list_lock);
+	llist_for_each_entry(ima_ns, ima_kill_list, cleanup_list)
+		list_del(&ima_ns->list);
+	up_write(&ima_ns_list_lock);
+
+	/* After removing ima namespace from the ima_ns_list, memory can be
+	 * freed. At this stage nothing should keep a reference to the given
+	 * namespace.
+	 */
+	llist_for_each_entry_safe(ima_ns, tmp, ima_kill_list, cleanup_list)
+		destroy_ima_ns(ima_ns);
+}
+
+static DECLARE_WORK(ima_cleanup_work, cleanup_ima);
+
 void free_ima_ns(struct kref *kref)
 {
-	struct ima_namespace *ns;
+	struct ima_namespace *ima_ns;
 
-	ns = container_of(kref, struct ima_namespace, kref);
+	ima_ns = container_of(kref, struct ima_namespace, kref);
+	/* Namespace can be destroyed instantly if no process ever was born
+	 * into it - it was never added to the ima_ns_list.
+	 */
+	if (!ima_ns->frozen) {
+		destroy_ima_ns(ima_ns);
+		return;
+	}
 
-	destroy_ima_ns(ns);
+	atomic_set(&ima_ns->inactive, 1);
+	if (llist_add(&ima_ns->cleanup_list, &cleanup_list))
+		queue_work(imans_wq, &ima_cleanup_work);
 }
 
 static inline struct ima_namespace *to_ima_ns(struct ns_common *ns)
@@ -168,8 +226,32 @@ static void imans_put(struct ns_common *ns)
 	put_ima_ns(to_ima_ns(ns));
 }
 
+static int imans_activate(struct ima_namespace *ima_ns)
+{
+	if (ima_ns == &init_ima_ns)
+		return 0;
+
+	if (ima_ns->frozen)
+		return 0;
+
+	mutex_lock(&frozen_lock);
+	if (ima_ns->frozen)
+		goto out;
+
+	ima_ns->frozen = true;
+
+	down_write(&ima_ns_list_lock);
+	list_add_tail(&ima_ns->list, &ima_ns_list);
+	up_write(&ima_ns_list_lock);
+out:
+	mutex_unlock(&frozen_lock);
+
+	return 0;
+}
+
 static int imans_install(struct nsset *nsset, struct ns_common *new)
 {
+	int res;
 	struct nsproxy *nsproxy = nsset->nsproxy;
 	struct ima_namespace *ns = to_ima_ns(new);
 
@@ -180,6 +262,10 @@ static int imans_install(struct nsset *nsset, struct ns_common *new)
 	    !ns_capable(nsset->cred->user_ns, CAP_SYS_ADMIN))
 		return -EPERM;
 
+	res = imans_activate(ns);
+	if (res)
+		return res;
+
 	get_ima_ns(ns);
 	put_ima_ns(nsproxy->ima_ns);
 	nsproxy->ima_ns = ns;
@@ -188,11 +274,12 @@ static int imans_install(struct nsset *nsset, struct ns_common *new)
 	put_ima_ns(nsproxy->ima_ns_for_children);
 	nsproxy->ima_ns_for_children = ns;
 
-	return 0;
+	return res;
 }
 
 int imans_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk)
 {
+	int res;
 	struct ns_common *nsc = &nsproxy->ima_ns_for_children->ns;
 	struct ima_namespace *ns = to_ima_ns(nsc);
 
@@ -200,11 +287,15 @@ int imans_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk)
 	if (nsproxy->ima_ns == nsproxy->ima_ns_for_children)
 		return 0;
 
+	res = imans_activate(ns);
+	if (res)
+		return res;
+
 	get_ima_ns(ns);
 	put_ima_ns(nsproxy->ima_ns);
 	nsproxy->ima_ns = ns;
 
-	return 0;
+	return res;
 }
 
 static struct user_namespace *imans_owner(struct ns_common *ns)
