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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox