diff options
author | Yan, Zheng <zyan@redhat.com> | 2016-09-14 02:53:05 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-10-03 10:13:50 -0400 |
commit | ce2728aaa82bbebae7d20345324af3f0f49eeb20 (patch) | |
tree | 731e14ae717753dbaf2771956266a1f36a6d856a | |
parent | db4a63aab43b2040292b2023512864702b5f9799 (diff) |
ceph: avoid accessing / when mounting a subpath
Accessing / causes failuire if the client has caps that restrict path
Signed-off-by: Yan, Zheng <zyan@redhat.com>
-rw-r--r-- | fs/ceph/super.c | 49 |
1 files changed, 20 insertions, 29 deletions
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index e247f6f0feb7..a29ffce98187 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -396,10 +396,12 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt, | |||
396 | */ | 396 | */ |
397 | dev_name_end = strchr(dev_name, '/'); | 397 | dev_name_end = strchr(dev_name, '/'); |
398 | if (dev_name_end) { | 398 | if (dev_name_end) { |
399 | fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL); | 399 | if (strlen(dev_name_end) > 1) { |
400 | if (!fsopt->server_path) { | 400 | fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL); |
401 | err = -ENOMEM; | 401 | if (!fsopt->server_path) { |
402 | goto out; | 402 | err = -ENOMEM; |
403 | goto out; | ||
404 | } | ||
403 | } | 405 | } |
404 | } else { | 406 | } else { |
405 | dev_name_end = dev_name + strlen(dev_name); | 407 | dev_name_end = dev_name + strlen(dev_name); |
@@ -788,15 +790,10 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc, | |||
788 | struct inode *inode = req->r_target_inode; | 790 | struct inode *inode = req->r_target_inode; |
789 | req->r_target_inode = NULL; | 791 | req->r_target_inode = NULL; |
790 | dout("open_root_inode success\n"); | 792 | dout("open_root_inode success\n"); |
791 | if (ceph_ino(inode) == CEPH_INO_ROOT && | 793 | root = d_make_root(inode); |
792 | fsc->sb->s_root == NULL) { | 794 | if (!root) { |
793 | root = d_make_root(inode); | 795 | root = ERR_PTR(-ENOMEM); |
794 | if (!root) { | 796 | goto out; |
795 | root = ERR_PTR(-ENOMEM); | ||
796 | goto out; | ||
797 | } | ||
798 | } else { | ||
799 | root = d_obtain_root(inode); | ||
800 | } | 797 | } |
801 | ceph_init_dentry(root); | 798 | ceph_init_dentry(root); |
802 | dout("open_root_inode success, root dentry is %p\n", root); | 799 | dout("open_root_inode success, root dentry is %p\n", root); |
@@ -825,17 +822,24 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc) | |||
825 | mutex_lock(&fsc->client->mount_mutex); | 822 | mutex_lock(&fsc->client->mount_mutex); |
826 | 823 | ||
827 | if (!fsc->sb->s_root) { | 824 | if (!fsc->sb->s_root) { |
825 | const char *path; | ||
828 | err = __ceph_open_session(fsc->client, started); | 826 | err = __ceph_open_session(fsc->client, started); |
829 | if (err < 0) | 827 | if (err < 0) |
830 | goto out; | 828 | goto out; |
831 | 829 | ||
832 | dout("mount opening root\n"); | 830 | if (!fsc->mount_options->server_path) { |
833 | root = open_root_dentry(fsc, "", started); | 831 | path = ""; |
832 | dout("mount opening path \\t\n"); | ||
833 | } else { | ||
834 | path = fsc->mount_options->server_path + 1; | ||
835 | dout("mount opening path %s\n", path); | ||
836 | } | ||
837 | root = open_root_dentry(fsc, path, started); | ||
834 | if (IS_ERR(root)) { | 838 | if (IS_ERR(root)) { |
835 | err = PTR_ERR(root); | 839 | err = PTR_ERR(root); |
836 | goto out; | 840 | goto out; |
837 | } | 841 | } |
838 | fsc->sb->s_root = root; | 842 | fsc->sb->s_root = dget(root); |
839 | first = 1; | 843 | first = 1; |
840 | 844 | ||
841 | err = ceph_fs_debugfs_init(fsc); | 845 | err = ceph_fs_debugfs_init(fsc); |
@@ -843,19 +847,6 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc) | |||
843 | goto fail; | 847 | goto fail; |
844 | } | 848 | } |
845 | 849 | ||
846 | if (!fsc->mount_options->server_path) { | ||
847 | root = fsc->sb->s_root; | ||
848 | dget(root); | ||
849 | } else { | ||
850 | const char *path = fsc->mount_options->server_path + 1; | ||
851 | dout("mount opening path %s\n", path); | ||
852 | root = open_root_dentry(fsc, path, started); | ||
853 | if (IS_ERR(root)) { | ||
854 | err = PTR_ERR(root); | ||
855 | goto fail; | ||
856 | } | ||
857 | } | ||
858 | |||
859 | fsc->mount_state = CEPH_MOUNT_MOUNTED; | 850 | fsc->mount_state = CEPH_MOUNT_MOUNTED; |
860 | dout("mount success\n"); | 851 | dout("mount success\n"); |
861 | mutex_unlock(&fsc->client->mount_mutex); | 852 | mutex_unlock(&fsc->client->mount_mutex); |