fs/namespace.c | 13 ++++++++++++- kernel/sysctl.c | 14 ++++++++++++++ tools/testing/selftests/mount_setattr/mount_setattr_test.c | 4 ++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index b696543adab8..0c9de99f73b7 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -43,6 +43,8 @@ static unsigned int m_hash_shift __read_mostly; static unsigned int mp_hash_mask __read_mostly; static unsigned int mp_hash_shift __read_mostly; +int sysctl_idmap_mounts __read_mostly = 0; + static __initdata unsigned long mhash_entries; static int __init set_mhash_entries(char *str) { @@ -3955,7 +3957,16 @@ static int can_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt) if (!is_anon_ns(mnt->mnt_ns)) return -EINVAL; - return 0; + /* + * So far, there are serious concerns about the safety of idmaps. + * This mechanism requires further upstream review. + */ + if( sysctl_idmap_mounts ) { + return 0; + } else { + pr_warn_once("VFS: idmapped mount is not enabled.\n"); + return -EPERM; + } } static struct mount *mount_setattr_prepare(struct mount_kattr *kattr, diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 083be6af29d7..b5a399ea1d7d 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -128,6 +128,11 @@ static int ten_thousand = 10000; #ifdef CONFIG_PERF_EVENTS static int six_hundred_forty_kb = 640 * 1024; #endif +#ifdef CONFIG_USER_NS +extern int sysctl_userns_restrict; +#endif +extern int sysctl_idmap_mounts; + /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */ static unsigned long dirty_bytes_min = 2 * PAGE_SIZE; @@ -2307,6 +2312,15 @@ static struct ctl_table kern_table[] = { .extra2 = &two, }, #endif + { + .procname = "idmap_mounts", + .data = &sysctl_idmap_mounts, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, { .procname = "ngroups_max", .data = &ngroups_max, diff --git a/tools/testing/selftests/mount_setattr/mount_setattr_test.c b/tools/testing/selftests/mount_setattr/mount_setattr_test.c index 8c5fea68ae67..ff5b3cc876ac 100644 --- a/tools/testing/selftests/mount_setattr/mount_setattr_test.c +++ b/tools/testing/selftests/mount_setattr/mount_setattr_test.c @@ -1321,7 +1321,7 @@ TEST_F(mount_setattr_idmapped, detached_mount_inside_current_mount_namespace) /* Changing mount properties on a detached mount. */ attr.userns_fd = get_userns_fd(0, 10000, 10000); ASSERT_GE(attr.userns_fd, 0); - ASSERT_EQ(sys_mount_setattr(open_tree_fd, "", + ASSERT_NE(sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr)), 0); ASSERT_EQ(close(attr.userns_fd), 0); ASSERT_EQ(close(open_tree_fd), 0); @@ -1353,7 +1353,7 @@ TEST_F(mount_setattr_idmapped, detached_mount_outside_current_mount_namespace) /* Changing mount properties on a detached mount. */ attr.userns_fd = get_userns_fd(0, 10000, 10000); ASSERT_GE(attr.userns_fd, 0); - ASSERT_EQ(sys_mount_setattr(open_tree_fd, "", + ASSERT_NE(sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr)), 0); ASSERT_EQ(close(attr.userns_fd), 0); ASSERT_EQ(close(open_tree_fd), 0);