stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Xiubo Li <xiubli@redhat.com>,
	Jeff Layton <jlayton@kernel.org>,
	Ilya Dryomov <idryomov@gmail.com>,
	Luis Henriques <lhenriques@suse.com>
Subject: [PATCH 5.5 43/44] ceph: remove the extra slashes in the server path
Date: Sat, 11 Apr 2020 14:10:03 +0200	[thread overview]
Message-ID: <20200411115501.051155230@linuxfoundation.org> (raw)
In-Reply-To: <20200411115456.934174282@linuxfoundation.org>

From: Xiubo Li <xiubli@redhat.com>

commit 4fbc0c711b2464ee1551850b85002faae0b775d5 upstream.

It's possible to pass the mount helper a server path that has more
than one contiguous slash character. For example:

  $ mount -t ceph 192.168.195.165:40176:/// /mnt/cephfs/

In the MDS server side the extra slashes of the server path will be
treated as snap dir, and then we can get the following debug logs:

  ceph:  mount opening path //
  ceph:  open_root_inode opening '//'
  ceph:  fill_trace 0000000059b8a3bc is_dentry 0 is_target 1
  ceph:  alloc_inode 00000000dc4ca00b
  ceph:  get_inode created new inode 00000000dc4ca00b 1.ffffffffffffffff ino 1
  ceph:  get_inode on 1=1.ffffffffffffffff got 00000000dc4ca00b

And then when creating any new file or directory under the mount
point, we can hit the following BUG_ON in ceph_fill_trace():

  BUG_ON(ceph_snap(dir) != dvino.snap);

Have the client ignore the extra slashes in the server path when
mounting. This will also canonicalize the path, so that identical mounts
can be consilidated.

1) "//mydir1///mydir//"
2) "/mydir1/mydir"
3) "/mydir1/mydir/"

Regardless of the internal treatment of these paths, the kernel still
stores the original string including the leading '/' for presentation
to userland.

URL: https://tracker.ceph.com/issues/42771
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Luis Henriques <lhenriques@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 fs/ceph/super.c |  122 ++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 102 insertions(+), 20 deletions(-)

--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -107,7 +107,6 @@ static int ceph_statfs(struct dentry *de
 	return 0;
 }
 
-
 static int ceph_sync_fs(struct super_block *sb, int wait)
 {
 	struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
@@ -211,7 +210,6 @@ struct ceph_parse_opts_ctx {
 
 /*
  * Parse the source parameter.  Distinguish the server list from the path.
- * Internally we do not include the leading '/' in the path.
  *
  * The source will look like:
  *     <server_spec>[,<server_spec>...]:[<path>]
@@ -232,12 +230,15 @@ static int ceph_parse_source(struct fs_p
 
 	dev_name_end = strchr(dev_name, '/');
 	if (dev_name_end) {
-		if (strlen(dev_name_end) > 1) {
-			kfree(fsopt->server_path);
-			fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
-			if (!fsopt->server_path)
-				return -ENOMEM;
-		}
+		kfree(fsopt->server_path);
+
+		/*
+		 * The server_path will include the whole chars from userland
+		 * including the leading '/'.
+		 */
+		fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
+		if (!fsopt->server_path)
+			return -ENOMEM;
 	} else {
 		dev_name_end = dev_name + strlen(dev_name);
 	}
@@ -461,6 +462,73 @@ static int strcmp_null(const char *s1, c
 	return strcmp(s1, s2);
 }
 
+/**
+ * path_remove_extra_slash - Remove the extra slashes in the server path
+ * @server_path: the server path and could be NULL
+ *
+ * Return NULL if the path is NULL or only consists of "/", or a string
+ * without any extra slashes including the leading slash(es) and the
+ * slash(es) at the end of the server path, such as:
+ * "//dir1////dir2///" --> "dir1/dir2"
+ */
+static char *path_remove_extra_slash(const char *server_path)
+{
+	const char *path = server_path;
+	const char *cur, *end;
+	char *buf, *p;
+	int len;
+
+	/* if the server path is omitted */
+	if (!path)
+		return NULL;
+
+	/* remove all the leading slashes */
+	while (*path == '/')
+		path++;
+
+	/* if the server path only consists of slashes */
+	if (*path == '\0')
+		return NULL;
+
+	len = strlen(path);
+
+	buf = kmalloc(len + 1, GFP_KERNEL);
+	if (!buf)
+		return ERR_PTR(-ENOMEM);
+
+	end = path + len;
+	p = buf;
+	do {
+		cur = strchr(path, '/');
+		if (!cur)
+			cur = end;
+
+		len = cur - path;
+
+		/* including one '/' */
+		if (cur != end)
+			len += 1;
+
+		memcpy(p, path, len);
+		p += len;
+
+		while (cur <= end && *cur == '/')
+			cur++;
+		path = cur;
+	} while (path < end);
+
+	*p = '\0';
+
+	/*
+	 * remove the last slash if there has and just to make sure that
+	 * we will get something like "dir1/dir2"
+	 */
+	if (*(--p) == '/')
+		*p = '\0';
+
+	return buf;
+}
+
 static int compare_mount_options(struct ceph_mount_options *new_fsopt,
 				 struct ceph_options *new_opt,
 				 struct ceph_fs_client *fsc)
@@ -468,6 +536,7 @@ static int compare_mount_options(struct
 	struct ceph_mount_options *fsopt1 = new_fsopt;
 	struct ceph_mount_options *fsopt2 = fsc->mount_options;
 	int ofs = offsetof(struct ceph_mount_options, snapdir_name);
+	char *p1, *p2;
 	int ret;
 
 	ret = memcmp(fsopt1, fsopt2, ofs);
@@ -480,9 +549,21 @@ static int compare_mount_options(struct
 	ret = strcmp_null(fsopt1->mds_namespace, fsopt2->mds_namespace);
 	if (ret)
 		return ret;
-	ret = strcmp_null(fsopt1->server_path, fsopt2->server_path);
+
+	p1 = path_remove_extra_slash(fsopt1->server_path);
+	if (IS_ERR(p1))
+		return PTR_ERR(p1);
+	p2 = path_remove_extra_slash(fsopt2->server_path);
+	if (IS_ERR(p2)) {
+		kfree(p1);
+		return PTR_ERR(p2);
+	}
+	ret = strcmp_null(p1, p2);
+	kfree(p1);
+	kfree(p2);
 	if (ret)
 		return ret;
+
 	ret = strcmp_null(fsopt1->fscache_uniq, fsopt2->fscache_uniq);
 	if (ret)
 		return ret;
@@ -788,7 +869,6 @@ static void destroy_caches(void)
 	ceph_fscache_unregister();
 }
 
-
 /*
  * ceph_umount_begin - initiate forced umount.  Tear down down the
  * mount, skipping steps that may hang while waiting for server(s).
@@ -868,9 +948,6 @@ out:
 	return root;
 }
 
-
-
-
 /*
  * mount: join the ceph cluster, and open root directory.
  */
@@ -885,7 +962,7 @@ static struct dentry *ceph_real_mount(st
 	mutex_lock(&fsc->client->mount_mutex);
 
 	if (!fsc->sb->s_root) {
-		const char *path;
+		const char *path, *p;
 		err = __ceph_open_session(fsc->client, started);
 		if (err < 0)
 			goto out;
@@ -897,17 +974,22 @@ static struct dentry *ceph_real_mount(st
 				goto out;
 		}
 
-		if (!fsc->mount_options->server_path) {
-			path = "";
-			dout("mount opening path \\t\n");
-		} else {
-			path = fsc->mount_options->server_path + 1;
-			dout("mount opening path %s\n", path);
+		p = path_remove_extra_slash(fsc->mount_options->server_path);
+		if (IS_ERR(p)) {
+			err = PTR_ERR(p);
+			goto out;
 		}
+		/* if the server path is omitted or just consists of '/' */
+		if (!p)
+			path = "";
+		else
+			path = p;
+		dout("mount opening path '%s'\n", path);
 
 		ceph_fs_debugfs_init(fsc);
 
 		root = open_root_dentry(fsc, path, started);
+		kfree(p);
 		if (IS_ERR(root)) {
 			err = PTR_ERR(root);
 			goto out;



  parent reply	other threads:[~2020-04-11 12:22 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-11 12:09 [PATCH 5.5 00/44] 5.5.17-rc1 review Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 01/44] cxgb4: fix MPS index overwrite when setting MAC address Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 02/44] ipv6: dont auto-add link-local address to lag ports Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 03/44] net: dsa: bcm_sf2: Do not register slave MDIO bus with OF Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 04/44] net: dsa: bcm_sf2: Ensure correct sub-node is parsed Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 05/44] net: dsa: mt7530: fix null pointer dereferencing in port5 setup Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 06/44] net: phy: micrel: kszphy_resume(): add delay after genphy_resume() before accessing PHY registers Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 07/44] net_sched: add a temporary refcnt for struct tcindex_data Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 08/44] net_sched: fix a missing refcnt in tcindex_init() Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 09/44] net: stmmac: dwmac1000: fix out-of-bounds mac address reg setting Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 10/44] slcan: Dont transmit uninitialized stack data in padding Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 11/44] tun: Dont put_page() for all negative return values from XDP program Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 12/44] mlxsw: spectrum_flower: Do not stop at FLOW_ACTION_VLAN_MANGLE Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 13/44] r8169: change back SG and TSO to be disabled by default Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 14/44] cxgb4: free MQPRIO resources in shutdown path Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 15/44] net: phy: at803x: fix clock sink configuration on ATH8030 and ATH8035 Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 16/44] s390: prevent leaking kernel address in BEAR Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 17/44] random: always use batched entropy for get_random_u{32,64} Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 18/44] usb: dwc3: gadget: Wrap around when skip TRBs Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 19/44] uapi: rename ext2_swab() to swab() and share globally in swab.h Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 20/44] slub: improve bit diffusion for freelist ptr obfuscation Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 21/44] include/uapi/linux/swab.h: fix userspace breakage, use __BITS_PER_LONG for swap Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 22/44] ubi: fastmap: Free unused fastmap anchor peb during detach Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 23/44] RDMA/ucma: Put a lock around every call to the rdma_cm layer Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 24/44] RDMA/cma: Teach lockdep about the order of rtnl and lock Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 25/44] RDMA/siw: Fix passive connection establishment Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 26/44] Bluetooth: RFCOMM: fix ODEBUG bug in rfcomm_dev_ioctl Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 27/44] RDMA/cm: Update num_paths in cma_resolve_iboe_route error flow Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 28/44] blk-mq: Keep set->nr_hw_queues and set->map[].nr_queues in sync Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 29/44] fbcon: fix null-ptr-deref in fbcon_switch Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 30/44] driver core: Reevaluate dev->links.need_for_probe as suppliers are added Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 31/44] iommu/vt-d: Allow devices with RMRRs to use identity domain Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 32/44] tools/accounting/getdelays.c: fix netlink attribute length Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 33/44] hwrng: imx-rngc - fix an error path Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 34/44] ACPI: PM: Add acpi_[un]register_wakeup_handler() Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 35/44] platform/x86: intel_int0002_vgpio: Use acpi_register_wakeup_handler() Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 36/44] ASoC: tas2562: Fixed incorrect amp_level setting Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 37/44] ASoC: jz4740-i2s: Fix divider written at incorrect offset in register Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 38/44] IB/hfi1: Call kobject_put() when kobject_init_and_add() fails Greg Kroah-Hartman
2020-04-11 12:09 ` [PATCH 5.5 39/44] IB/hfi1: Fix memory leaks in sysfs registration and unregistration Greg Kroah-Hartman
2020-04-11 12:10 ` [PATCH 5.5 40/44] IB/mlx5: Replace tunnel mpls capability bits for tunnel_offloads Greg Kroah-Hartman
2020-04-11 12:10 ` [PATCH 5.5 41/44] ARM: imx: Enable ARM_ERRATA_814220 for i.MX6UL and i.MX7D Greg Kroah-Hartman
2020-04-11 12:10 ` [PATCH 5.5 42/44] ARM: imx: only select ARM_ERRATA_814220 for ARMv7-A Greg Kroah-Hartman
2020-04-11 12:10 ` Greg Kroah-Hartman [this message]
2020-04-11 12:10 ` [PATCH 5.5 44/44] ceph: canonicalize server path in place Greg Kroah-Hartman
2020-04-11 20:42 ` [PATCH 5.5 00/44] 5.5.17-rc1 review Guenter Roeck
2020-04-12  7:04 ` Naresh Kamboju
2020-04-14 10:36 ` Jon Hunter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200411115501.051155230@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=idryomov@gmail.com \
    --cc=jlayton@kernel.org \
    --cc=lhenriques@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=xiubli@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).