aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 4dfcaf05d17c..9ddc86f93221 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1269,7 +1269,7 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
1269 goto dput_and_out; 1269 goto dput_and_out;
1270 1270
1271 retval = -EPERM; 1271 retval = -EPERM;
1272 if (!capable(CAP_SYS_ADMIN)) 1272 if (!ns_capable(mnt->mnt_ns->user_ns, CAP_SYS_ADMIN))
1273 goto dput_and_out; 1273 goto dput_and_out;
1274 1274
1275 retval = do_umount(mnt, flags); 1275 retval = do_umount(mnt, flags);
@@ -1295,7 +1295,7 @@ SYSCALL_DEFINE1(oldumount, char __user *, name)
1295 1295
1296static int mount_is_safe(struct path *path) 1296static int mount_is_safe(struct path *path)
1297{ 1297{
1298 if (capable(CAP_SYS_ADMIN)) 1298 if (ns_capable(real_mount(path->mnt)->mnt_ns->user_ns, CAP_SYS_ADMIN))
1299 return 0; 1299 return 0;
1300 return -EPERM; 1300 return -EPERM;
1301#ifdef notyet 1301#ifdef notyet
@@ -1633,7 +1633,7 @@ static int do_change_type(struct path *path, int flag)
1633 int type; 1633 int type;
1634 int err = 0; 1634 int err = 0;
1635 1635
1636 if (!capable(CAP_SYS_ADMIN)) 1636 if (!ns_capable(mnt->mnt_ns->user_ns, CAP_SYS_ADMIN))
1637 return -EPERM; 1637 return -EPERM;
1638 1638
1639 if (path->dentry != path->mnt->mnt_root) 1639 if (path->dentry != path->mnt->mnt_root)
@@ -1797,7 +1797,7 @@ static int do_move_mount(struct path *path, const char *old_name)
1797 struct mount *p; 1797 struct mount *p;
1798 struct mount *old; 1798 struct mount *old;
1799 int err = 0; 1799 int err = 0;
1800 if (!capable(CAP_SYS_ADMIN)) 1800 if (!ns_capable(real_mount(path->mnt)->mnt_ns->user_ns, CAP_SYS_ADMIN))
1801 return -EPERM; 1801 return -EPERM;
1802 if (!old_name || !*old_name) 1802 if (!old_name || !*old_name)
1803 return -EINVAL; 1803 return -EINVAL;
@@ -1884,21 +1884,6 @@ static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
1884 return ERR_PTR(err); 1884 return ERR_PTR(err);
1885} 1885}
1886 1886
1887static struct vfsmount *
1888do_kern_mount(const char *fstype, int flags, const char *name, void *data)
1889{
1890 struct file_system_type *type = get_fs_type(fstype);
1891 struct vfsmount *mnt;
1892 if (!type)
1893 return ERR_PTR(-ENODEV);
1894 mnt = vfs_kern_mount(type, flags, name, data);
1895 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
1896 !mnt->mnt_sb->s_subtype)
1897 mnt = fs_set_subtype(mnt, fstype);
1898 put_filesystem(type);
1899 return mnt;
1900}
1901
1902/* 1887/*
1903 * add a mount into a namespace's mount tree 1888 * add a mount into a namespace's mount tree
1904 */ 1889 */
@@ -1944,20 +1929,46 @@ unlock:
1944 * create a new mount for userspace and request it to be added into the 1929 * create a new mount for userspace and request it to be added into the
1945 * namespace's tree 1930 * namespace's tree
1946 */ 1931 */
1947static int do_new_mount(struct path *path, const char *type, int flags, 1932static int do_new_mount(struct path *path, const char *fstype, int flags,
1948 int mnt_flags, const char *name, void *data) 1933 int mnt_flags, const char *name, void *data)
1949{ 1934{
1935 struct file_system_type *type;
1936 struct user_namespace *user_ns;
1950 struct vfsmount *mnt; 1937 struct vfsmount *mnt;
1951 int err; 1938 int err;
1952 1939
1953 if (!type) 1940 if (!fstype)
1954 return -EINVAL; 1941 return -EINVAL;
1955 1942
1956 /* we need capabilities... */ 1943 /* we need capabilities... */
1957 if (!capable(CAP_SYS_ADMIN)) 1944 user_ns = real_mount(path->mnt)->mnt_ns->user_ns;
1945 if (!ns_capable(user_ns, CAP_SYS_ADMIN))
1958 return -EPERM; 1946 return -EPERM;
1959 1947
1960 mnt = do_kern_mount(type, flags, name, data); 1948 type = get_fs_type(fstype);
1949 if (!type)
1950 return -ENODEV;
1951
1952 if (user_ns != &init_user_ns) {
1953 if (!(type->fs_flags & FS_USERNS_MOUNT)) {
1954 put_filesystem(type);
1955 return -EPERM;
1956 }
1957 /* Only in special cases allow devices from mounts
1958 * created outside the initial user namespace.
1959 */
1960 if (!(type->fs_flags & FS_USERNS_DEV_MOUNT)) {
1961 flags |= MS_NODEV;
1962 mnt_flags |= MNT_NODEV;
1963 }
1964 }
1965
1966 mnt = vfs_kern_mount(type, flags, name, data);
1967 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
1968 !mnt->mnt_sb->s_subtype)
1969 mnt = fs_set_subtype(mnt, fstype);
1970
1971 put_filesystem(type);
1961 if (IS_ERR(mnt)) 1972 if (IS_ERR(mnt))
1962 return PTR_ERR(mnt); 1973 return PTR_ERR(mnt);
1963 1974
@@ -2549,7 +2560,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2549 struct mount *new_mnt, *root_mnt; 2560 struct mount *new_mnt, *root_mnt;
2550 int error; 2561 int error;
2551 2562
2552 if (!capable(CAP_SYS_ADMIN)) 2563 if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN))
2553 return -EPERM; 2564 return -EPERM;
2554 2565
2555 error = user_path_dir(new_root, &new); 2566 error = user_path_dir(new_root, &new);
@@ -2631,8 +2642,13 @@ static void __init init_mount_tree(void)
2631 struct vfsmount *mnt; 2642 struct vfsmount *mnt;
2632 struct mnt_namespace *ns; 2643 struct mnt_namespace *ns;
2633 struct path root; 2644 struct path root;
2645 struct file_system_type *type;
2634 2646
2635 mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); 2647 type = get_fs_type("rootfs");
2648 if (!type)
2649 panic("Can't find rootfs type");
2650 mnt = vfs_kern_mount(type, 0, "rootfs", NULL);
2651 put_filesystem(type);
2636 if (IS_ERR(mnt)) 2652 if (IS_ERR(mnt))
2637 panic("Can't create rootfs"); 2653 panic("Can't create rootfs");
2638 2654
@@ -2757,7 +2773,8 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns)
2757 struct mnt_namespace *mnt_ns = ns; 2773 struct mnt_namespace *mnt_ns = ns;
2758 struct path root; 2774 struct path root;
2759 2775
2760 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_CHROOT)) 2776 if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
2777 !nsown_capable(CAP_SYS_CHROOT))
2761 return -EINVAL; 2778 return -EINVAL;
2762 2779
2763 if (fs->users != 1) 2780 if (fs->users != 1)