From: Al Viro <viro@zeniv.linux.org.uk>
To: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Cc: "luis@igalia.com" <luis@igalia.com>,
"ceph-devel@vger.kernel.org" <ceph-devel@vger.kernel.org>,
"jlayton@kernel.org" <jlayton@kernel.org>,
"idryomov@gmail.com" <idryomov@gmail.com>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>
Subject: Re: [RFC] odd check in ceph_encode_encrypted_dname()
Date: Tue, 18 Feb 2025 23:52:46 +0000 [thread overview]
Message-ID: <20250218235246.GA191109@ZenIV> (raw)
In-Reply-To: <20250218012132.GJ1977892@ZenIV>
On Tue, Feb 18, 2025 at 01:21:32AM +0000, Al Viro wrote:
> See the problem? strrchr() expects a NUL-terminated string; giving it an
> array that has no zero bytes in it is an UB.
>
> That one is -stable fodder on its own, IMO...
FWIW, it's more unpleasant; there are other call chains for parse_longname()
where it's not feasible to NUL-terminate in place. I suspect that the
patch below is a better way to handle that. Comments?
From ed016e5ea89550b567306207ba3ca8b60e147d89 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Tue, 18 Feb 2025 17:57:17 -0500
Subject: [PATCH 1/3] [ceph] parse_longname(): strrchr() expects NUL-terminated
string
... and parse_longname() is not guaranteed that. That's the reason
why it uses kmemdup_nul() to build the argument for kstrtou64();
the problem is, kstrtou64() is not the only thing that need it.
Just get a NUL-terminated copy of the entire thing and be done
with that...
Fixes: dd66df0053ef "ceph: add support for encrypted snapshot names"
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ceph/crypto.c | 32 ++++++++++++--------------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c
index 3b3c4d8d401e..164e7981aecb 100644
--- a/fs/ceph/crypto.c
+++ b/fs/ceph/crypto.c
@@ -215,35 +215,30 @@ static struct inode *parse_longname(const struct inode *parent,
struct ceph_client *cl = ceph_inode_to_client(parent);
struct inode *dir = NULL;
struct ceph_vino vino = { .snap = CEPH_NOSNAP };
- char *inode_number;
char *name_end;
- int orig_len = *name_len;
int ret = -EIO;
-
+ /* NUL-terminate */
+ char *s __free(kfree) = kmemdup_nul(name, *name_len, GFP_KERNEL);
+ if (!s)
+ return ERR_PTR(-ENOMEM);
/* Skip initial '_' */
- name++;
- name_end = strrchr(name, '_');
+ s++;
+ name_end = strrchr(s, '_');
if (!name_end) {
- doutc(cl, "failed to parse long snapshot name: %s\n", name);
+ doutc(cl, "failed to parse long snapshot name: %s\n", s);
return ERR_PTR(-EIO);
}
- *name_len = (name_end - name);
+ *name_len = (name_end - s);
if (*name_len <= 0) {
pr_err_client(cl, "failed to parse long snapshot name\n");
return ERR_PTR(-EIO);
}
/* Get the inode number */
- inode_number = kmemdup_nul(name_end + 1,
- orig_len - *name_len - 2,
- GFP_KERNEL);
- if (!inode_number)
- return ERR_PTR(-ENOMEM);
- ret = kstrtou64(inode_number, 10, &vino.ino);
+ ret = kstrtou64(name_end + 1, 10, &vino.ino);
if (ret) {
- doutc(cl, "failed to parse inode number: %s\n", name);
- dir = ERR_PTR(ret);
- goto out;
+ doutc(cl, "failed to parse inode number: %s\n", s);
+ return ERR_PTR(ret);
}
/* And finally the inode */
@@ -252,11 +247,8 @@ static struct inode *parse_longname(const struct inode *parent,
/* This can happen if we're not mounting cephfs on the root */
dir = ceph_get_inode(parent->i_sb, vino, NULL);
if (IS_ERR(dir))
- doutc(cl, "can't find inode %s (%s)\n", inode_number, name);
+ doutc(cl, "can't find inode %s (%s)\n", name_end + 1, name);
}
-
-out:
- kfree(inode_number);
return dir;
}
--
2.39.5
next prev parent reply other threads:[~2025-02-18 23:52 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-14 2:47 [RFC] odd check in ceph_encode_encrypted_dname() Al Viro
2025-02-14 3:28 ` Al Viro
2025-02-14 14:05 ` Luis Henriques
2025-02-14 15:41 ` Jeff Layton
2025-02-14 16:05 ` Luis Henriques
2025-02-15 4:46 ` Al Viro
2025-02-15 4:47 ` [PATCH 1/2] prep for ceph_encode_encrypted_fname() fixes Al Viro
2025-02-15 12:41 ` Jeff Layton
2025-02-15 4:47 ` [PATCH 2/2] ceph: fix a race with rename() in ceph_mdsc_build_path() Al Viro
2025-02-15 12:42 ` Jeff Layton
2025-02-15 15:39 ` [RFC] odd check in ceph_encode_encrypted_dname() Luis Henriques
2025-02-17 17:56 ` Viacheslav Dubeyko
2025-02-17 18:48 ` Luis Henriques
2025-02-17 22:04 ` Viacheslav Dubeyko
2025-02-18 1:21 ` Al Viro
2025-02-18 23:52 ` Al Viro [this message]
2025-02-19 0:58 ` Viacheslav Dubeyko
2025-02-19 2:18 ` Al Viro
2025-02-19 23:22 ` Viacheslav Dubeyko
2025-02-21 1:21 ` Viacheslav Dubeyko
2025-02-14 15:30 ` Jeff Layton
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=20250218235246.GA191109@ZenIV \
--to=viro@zeniv.linux.org.uk \
--cc=Slava.Dubeyko@ibm.com \
--cc=ceph-devel@vger.kernel.org \
--cc=idryomov@gmail.com \
--cc=jlayton@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=luis@igalia.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.