From: Max Kellermann max.kellermann@ionos.com
commit 550f7ca98ee028a606aa75705a7e77b1bd11720f upstream.
If the full path to be built by ceph_mdsc_build_path() happens to be longer than PATH_MAX, then this function will enter an endless (retry) loop, effectively blocking the whole task. Most of the machine becomes unusable, making this a very simple and effective DoS vulnerability.
I cannot imagine why this retry was ever implemented, but it seems rather useless and harmful to me. Let's remove it and fail with ENAMETOOLONG instead.
Cc: stable@vger.kernel.org Reported-by: Dario Weißer dario@cure53.de Signed-off-by: Max Kellermann max.kellermann@ionos.com Reviewed-by: Alex Markuze amarkuze@redhat.com Signed-off-by: Ilya Dryomov idryomov@gmail.com [idryomov@gmail.com: backport to 6.1: pr_warn() is still in use] --- fs/ceph/mds_client.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index da9fcf48ab6c..741ca7d10032 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2447,12 +2447,11 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase,
if (pos < 0) { /* - * A rename didn't occur, but somehow we didn't end up where - * we thought we would. Throw a warning and try again. + * The path is longer than PATH_MAX and this function + * cannot ever succeed. Creating paths that long is + * possible with Ceph, but Linux cannot use them. */ - pr_warn("build_path did not end path lookup where " - "expected, pos is %d\n", pos); - goto retry; + return ERR_PTR(-ENAMETOOLONG); }
*pbase = base;
[ Sasha's backport helper bot ]
Hi,
The upstream commit SHA1 provided is correct: 550f7ca98ee028a606aa75705a7e77b1bd11720f
WARNING: Author mismatch between patch and upstream commit: Backport author: Ilya Dryomovidryomov@gmail.com Commit author: Max Kellermannmax.kellermann@ionos.com
Status in newer kernel trees: 6.12.y | Present (different SHA1: 99a37ab76a31) 6.6.y | Present (different SHA1: 82dfe5074a06) 6.1.y | Not found
Note: The patch differs from the upstream commit: --- 1: 550f7ca98ee0 ! 1: 9c81f6f042e7 ceph: give up on paths longer than PATH_MAX @@ Metadata ## Commit message ## ceph: give up on paths longer than PATH_MAX
+ commit 550f7ca98ee028a606aa75705a7e77b1bd11720f upstream. + If the full path to be built by ceph_mdsc_build_path() happens to be longer than PATH_MAX, then this function will enter an endless (retry) loop, effectively blocking the whole task. Most of the machine @@ Commit message Signed-off-by: Max Kellermann max.kellermann@ionos.com Reviewed-by: Alex Markuze amarkuze@redhat.com Signed-off-by: Ilya Dryomov idryomov@gmail.com + [idryomov@gmail.com: backport to 6.1: pr_warn() is still in use]
## fs/ceph/mds_client.c ## -@@ fs/ceph/mds_client.c: char *ceph_mdsc_build_path(struct ceph_mds_client *mdsc, struct dentry *dentry, +@@ fs/ceph/mds_client.c: char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase,
if (pos < 0) { /* @@ fs/ceph/mds_client.c: char *ceph_mdsc_build_path(struct ceph_mds_client *mdsc, s + * cannot ever succeed. Creating paths that long is + * possible with Ceph, but Linux cannot use them. */ -- pr_warn_client(cl, "did not end path lookup where expected (pos = %d)\n", -- pos); +- pr_warn("build_path did not end path lookup where " +- "expected, pos is %d\n", pos); - goto retry; + return ERR_PTR(-ENAMETOOLONG); } ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.1.y | Success | Failed | | stable/linux-5.10.y | Success | Success |
Build Errors: Build error for stable/linux-6.1.y: bash: line 1: cd: /home/sasha/build/linus-next: No such file or directory
linux-stable-mirror@lists.linaro.org