diff --git a/fs/namespace.c b/fs/namespace.c
index b4c7d07..01eb901 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2402,6 +2402,9 @@ static __latent_entropy struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *m
 	struct mount *new;
 	int copy_flags;
 
+	if (!gr_acl_is_mnt_ns_allowed())
+		return ERR_PTR(-EPERM);
+
 	new_ns = alloc_mnt_ns(user_ns);
 	if (IS_ERR(new_ns))
 		return new_ns;
diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c
index c0793fd..2306a1e 100644
--- a/grsecurity/gracl.c
+++ b/grsecurity/gracl.c
@@ -51,6 +51,8 @@ static struct inodev_db inodev_set;
 
 static struct path real_root;
 
+static struct mnt_namespace *init_mnt_ns;
+
 static struct acl_subj_map_db subj_map_set;
 
 static struct acl_role_label *default_role;
@@ -94,6 +96,7 @@ extern struct vfsmount *hugetlbfs_vfsmount[HUGE_MAX_HSTATE];
 
 static struct acl_object_label *fakefs_obj_rw;
 static struct acl_object_label *fakefs_obj_rwx;
+static struct acl_object_label *fakefs_obj_all;
 
 extern int gr_init_uidset(void);
 extern void gr_free_uidset(void);
@@ -1017,11 +1020,13 @@ init_variables(const struct gr_arg *arg)
 
 	/* set up the stack that holds allocation info */
 
-	stacksize = arg->role_db.num_pointers + 5;
+	stacksize = arg->role_db.num_pointers + 6;
 
 	if (!acl_alloc_stack_init(stacksize))
 		return 1;
 
+	init_mnt_ns = get_mnt_ns(init_pid_ns.child_reaper->nsproxy->mnt_ns);
+
 	/* grab reference for the real root dentry and vfsmount */
 	get_fs_root(reaper->fs, &real_root);
 	
@@ -1039,6 +1044,11 @@ init_variables(const struct gr_arg *arg)
 		return 1;
 	fakefs_obj_rwx->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
 
+	fakefs_obj_all = acl_alloc(sizeof(struct acl_object_label));
+	if (fakefs_obj_all == NULL)
+		return 1;
+	fakefs_obj_all->mode = GR_FIND | GR_READ | GR_APPEND | GR_WRITE | GR_EXEC | GR_SETID | GR_CREATE | GR_DELETE | GR_LINK;
+
 	subj_map_set.s_hash =
 	    (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
 	acl_role_set.r_hash =
@@ -1113,6 +1123,8 @@ free_variables(void)
 	path_put(&real_root);
 	memset(&real_root, 0, sizeof(real_root));
 
+	put_mnt_ns(init_mnt_ns);
+
 	/* free all object hash tables */
 
 	FOR_EACH_ROLE_START(r)
@@ -1959,6 +1971,11 @@ __chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
 	br_read_lock(&vfsmount_lock);
 	write_seqlock(&rename_lock);
 
+	if (unlikely((subj->mode & GR_CREATEMNTNS) && current->nsproxy->mnt_ns != init_mnt_ns)) {
+		retval = fakefs_obj_all;
+		goto out;
+	}
+
 	if (unlikely((mnt == shm_mnt && dentry->d_inode->i_nlink == 0) || mnt == pipe_mnt ||
 #ifdef CONFIG_NET
 	    mnt == sock_mnt ||
diff --git a/grsecurity/gracl_fs.c b/grsecurity/gracl_fs.c
index a340c17..a0aa091 100644
--- a/grsecurity/gracl_fs.c
+++ b/grsecurity/gracl_fs.c
@@ -8,6 +8,18 @@
 #include <linux/grinternal.h>
 #include <linux/gracl.h>
 
+int gr_acl_is_mnt_ns_allowed(void)
+{
+	if (unlikely(!gr_acl_is_enabled()))
+		return 1;
+	
+	if (current->acl->mode & GR_CREATEMNTNS)
+		return 1;
+
+	gr_log_noargs(GR_DONT_AUDIT, GR_CREATEMNTNS_MSG);
+	return 0;
+}
+
 umode_t
 gr_acl_umask(void)
 {
diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c
index ce65ceb..5bdab3d 100644
--- a/grsecurity/grsec_disabled.c
+++ b/grsecurity/grsec_disabled.c
@@ -417,6 +417,11 @@ int gr_acl_enable_at_secure(void)
 	return 0;
 }
 
+int gr_acl_is_mnt_ns_allowed(void)
+{
+	return 1;
+}
+
 dev_t gr_get_dev_from_dentry(struct dentry *dentry)
 {
 	return dentry->d_sb->s_dev;
diff --git a/include/linux/grdefs.h b/include/linux/grdefs.h
index be66033..a57a7c6 100644
--- a/include/linux/grdefs.h
+++ b/include/linux/grdefs.h
@@ -88,7 +88,8 @@ enum {
 	GR_POVERRIDE	= 0x00010000,
 	GR_KERNELAUTH	= 0x00020000,
 	GR_ATSECURE	= 0x00040000,
-	GR_SHMEXEC	= 0x00080000
+	GR_SHMEXEC	= 0x00080000,
+	GR_CREATEMNTNS	= 0x00100000
 };
 
 enum {
diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h
index a4396b5..6f65d4a 100644
--- a/include/linux/grmsg.h
+++ b/include/linux/grmsg.h
@@ -111,3 +111,4 @@
 #define GR_SYMLINKOWNER_MSG "denied following symlink %.950s since symlink owner %u does not match target owner %u, by "
 #define GR_BRUTE_DAEMON_MSG "bruteforce prevention initiated for the next 30 minutes or until service restarted, stalling each fork 30 seconds.  Please investigate the crash report for "
 #define GR_BRUTE_SUID_MSG "bruteforce prevention initiated due to crash of %.950s against uid %u, banning suid/sgid execs for %u minutes.  Please investigate the crash report for "
+#define GR_CREATEMNTNS_MSG "denied mnt namespace creation by "
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
index d6f5a21..991380e 100644
--- a/include/linux/grsecurity.h
+++ b/include/linux/grsecurity.h
@@ -59,6 +59,8 @@ int gr_handle_rawio(const struct inode *inode);
 void gr_handle_ioperm(void);
 void gr_handle_iopl(void);
 
+int gr_acl_is_mnt_ns_allowed(void);
+
 umode_t gr_acl_umask(void);
 
 int gr_tpe_allow(const struct file *file);
