Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce2728aa authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov
Browse files

ceph: avoid accessing / when mounting a subpath



Accessing / causes failuire if the client has caps that restrict path

Signed-off-by: default avatarYan, Zheng <zyan@redhat.com>
parent db4a63aa
Loading
Loading
Loading
Loading
+20 −29
Original line number Original line Diff line number Diff line
@@ -396,11 +396,13 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
	 */
	 */
	dev_name_end = strchr(dev_name, '/');
	dev_name_end = strchr(dev_name, '/');
	if (dev_name_end) {
	if (dev_name_end) {
		if (strlen(dev_name_end) > 1) {
			fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
			fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
			if (!fsopt->server_path) {
			if (!fsopt->server_path) {
				err = -ENOMEM;
				err = -ENOMEM;
				goto out;
				goto out;
			}
			}
		}
	} else {
	} else {
		dev_name_end = dev_name + strlen(dev_name);
		dev_name_end = dev_name + strlen(dev_name);
	}
	}
@@ -788,16 +790,11 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
		struct inode *inode = req->r_target_inode;
		struct inode *inode = req->r_target_inode;
		req->r_target_inode = NULL;
		req->r_target_inode = NULL;
		dout("open_root_inode success\n");
		dout("open_root_inode success\n");
		if (ceph_ino(inode) == CEPH_INO_ROOT &&
		    fsc->sb->s_root == NULL) {
		root = d_make_root(inode);
		root = d_make_root(inode);
		if (!root) {
		if (!root) {
			root = ERR_PTR(-ENOMEM);
			root = ERR_PTR(-ENOMEM);
			goto out;
			goto out;
		}
		}
		} else {
			root = d_obtain_root(inode);
		}
		ceph_init_dentry(root);
		ceph_init_dentry(root);
		dout("open_root_inode success, root dentry is %p\n", root);
		dout("open_root_inode success, root dentry is %p\n", root);
	} else {
	} else {
@@ -825,17 +822,24 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
	mutex_lock(&fsc->client->mount_mutex);
	mutex_lock(&fsc->client->mount_mutex);


	if (!fsc->sb->s_root) {
	if (!fsc->sb->s_root) {
		const char *path;
		err = __ceph_open_session(fsc->client, started);
		err = __ceph_open_session(fsc->client, started);
		if (err < 0)
		if (err < 0)
			goto out;
			goto out;


		dout("mount opening root\n");
		if (!fsc->mount_options->server_path) {
		root = open_root_dentry(fsc, "", started);
			path = "";
			dout("mount opening path \\t\n");
		} else {
			path = fsc->mount_options->server_path + 1;
			dout("mount opening path %s\n", path);
		}
		root = open_root_dentry(fsc, path, started);
		if (IS_ERR(root)) {
		if (IS_ERR(root)) {
			err = PTR_ERR(root);
			err = PTR_ERR(root);
			goto out;
			goto out;
		}
		}
		fsc->sb->s_root = root;
		fsc->sb->s_root = dget(root);
		first = 1;
		first = 1;


		err = ceph_fs_debugfs_init(fsc);
		err = ceph_fs_debugfs_init(fsc);
@@ -843,19 +847,6 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
			goto fail;
			goto fail;
	}
	}


	if (!fsc->mount_options->server_path) {
		root = fsc->sb->s_root;
		dget(root);
	} else {
		const char *path = fsc->mount_options->server_path + 1;
		dout("mount opening path %s\n", path);
		root = open_root_dentry(fsc, path, started);
		if (IS_ERR(root)) {
			err = PTR_ERR(root);
			goto fail;
		}
	}

	fsc->mount_state = CEPH_MOUNT_MOUNTED;
	fsc->mount_state = CEPH_MOUNT_MOUNTED;
	dout("mount success\n");
	dout("mount success\n");
	mutex_unlock(&fsc->client->mount_mutex);
	mutex_unlock(&fsc->client->mount_mutex);