Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Yan, Zheng and committed by
Ilya Dryomov
ce2728aa db4a63aa

+20 -29
+20 -29
fs/ceph/super.c
··· 396 396 */ 397 397 dev_name_end = strchr(dev_name, '/'); 398 398 if (dev_name_end) { 399 - fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL); 400 - if (!fsopt->server_path) { 401 - err = -ENOMEM; 402 - goto out; 399 + if (strlen(dev_name_end) > 1) { 400 + fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL); 401 + if (!fsopt->server_path) { 402 + err = -ENOMEM; 403 + goto out; 404 + } 403 405 } 404 406 } else { 405 407 dev_name_end = dev_name + strlen(dev_name); ··· 790 788 struct inode *inode = req->r_target_inode; 791 789 req->r_target_inode = NULL; 792 790 dout("open_root_inode success\n"); 793 - if (ceph_ino(inode) == CEPH_INO_ROOT && 794 - fsc->sb->s_root == NULL) { 795 - root = d_make_root(inode); 796 - if (!root) { 797 - root = ERR_PTR(-ENOMEM); 798 - goto out; 799 - } 800 - } else { 801 - root = d_obtain_root(inode); 791 + root = d_make_root(inode); 792 + if (!root) { 793 + root = ERR_PTR(-ENOMEM); 794 + goto out; 802 795 } 803 796 ceph_init_dentry(root); 804 797 dout("open_root_inode success, root dentry is %p\n", root); ··· 822 825 mutex_lock(&fsc->client->mount_mutex); 823 826 824 827 if (!fsc->sb->s_root) { 828 + const char *path; 825 829 err = __ceph_open_session(fsc->client, started); 826 830 if (err < 0) 827 831 goto out; 828 832 829 - dout("mount opening root\n"); 830 - root = open_root_dentry(fsc, "", started); 833 + if (!fsc->mount_options->server_path) { 834 + path = ""; 835 + dout("mount opening path \\t\n"); 836 + } else { 837 + path = fsc->mount_options->server_path + 1; 838 + dout("mount opening path %s\n", path); 839 + } 840 + root = open_root_dentry(fsc, path, started); 831 841 if (IS_ERR(root)) { 832 842 err = PTR_ERR(root); 833 843 goto out; 834 844 } 835 - fsc->sb->s_root = root; 845 + fsc->sb->s_root = dget(root); 836 846 first = 1; 837 847 838 848 err = ceph_fs_debugfs_init(fsc); 839 849 if (err < 0) 840 850 goto fail; 841 - } 842 - 843 - if (!fsc->mount_options->server_path) { 844 - root = fsc->sb->s_root; 845 - dget(root); 846 - } else { 847 - const char *path = fsc->mount_options->server_path + 1; 848 - dout("mount opening path %s\n", path); 849 - root = open_root_dentry(fsc, path, started); 850 - if (IS_ERR(root)) { 851 - err = PTR_ERR(root); 852 - goto fail; 853 - } 854 851 } 855 852 856 853 fsc->mount_state = CEPH_MOUNT_MOUNTED;