From: Al Viro <viro@zeniv.linux.org.uk>
To: Luis Henriques <luis@igalia.com>
Cc: Jeff Layton <jlayton@kernel.org>,
ceph-devel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
Ilya Dryomov <idryomov@gmail.com>
Subject: [PATCH 1/2] prep for ceph_encode_encrypted_fname() fixes
Date: Sat, 15 Feb 2025 04:47:14 +0000 [thread overview]
Message-ID: <20250215044714.GA3451131@ZenIV> (raw)
In-Reply-To: <20250215044616.GF1977892@ZenIV>
ceph_encode_encrypted_dname() would be better off with plaintext name
already copied into buffer; we'll lift that into the callers on the
next step, which will allow to fix UAF on races with rename; for now
copy it in the very beginning of ceph_encode_encrypted_dname().
That has a pleasant side benefit - we don't need to mess with tmp_buf
anymore (i.e. that's 256 bytes off the stack footprint).
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
fs/ceph/crypto.c | 40 +++++++++++++++++-----------------------
1 file changed, 17 insertions(+), 23 deletions(-)
diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c
index 3b3c4d8d401e..09346b91215a 100644
--- a/fs/ceph/crypto.c
+++ b/fs/ceph/crypto.c
@@ -265,31 +265,28 @@ int ceph_encode_encrypted_dname(struct inode *parent, struct qstr *d_name,
{
struct ceph_client *cl = ceph_inode_to_client(parent);
struct inode *dir = parent;
- struct qstr iname;
+ char *p = buf;
u32 len;
int name_len;
int elen;
int ret;
u8 *cryptbuf = NULL;
- iname.name = d_name->name;
- name_len = d_name->len;
+ memcpy(buf, d_name->name, d_name->len);
+ elen = d_name->len;
+
+ name_len = elen;
/* Handle the special case of snapshot names that start with '_' */
- if ((ceph_snap(dir) == CEPH_SNAPDIR) && (name_len > 0) &&
- (iname.name[0] == '_')) {
- dir = parse_longname(parent, iname.name, &name_len);
+ if (ceph_snap(dir) == CEPH_SNAPDIR && *p == '_') {
+ dir = parse_longname(parent, p, &name_len);
if (IS_ERR(dir))
return PTR_ERR(dir);
- iname.name++; /* skip initial '_' */
+ p++; /* skip initial '_' */
}
- iname.len = name_len;
- if (!fscrypt_has_encryption_key(dir)) {
- memcpy(buf, d_name->name, d_name->len);
- elen = d_name->len;
+ if (!fscrypt_has_encryption_key(dir))
goto out;
- }
/*
* Convert cleartext d_name to ciphertext. If result is longer than
@@ -297,7 +294,7 @@ int ceph_encode_encrypted_dname(struct inode *parent, struct qstr *d_name,
*
* See: fscrypt_setup_filename
*/
- if (!fscrypt_fname_encrypted_size(dir, iname.len, NAME_MAX, &len)) {
+ if (!fscrypt_fname_encrypted_size(dir, name_len, NAME_MAX, &len)) {
elen = -ENAMETOOLONG;
goto out;
}
@@ -310,7 +307,9 @@ int ceph_encode_encrypted_dname(struct inode *parent, struct qstr *d_name,
goto out;
}
- ret = fscrypt_fname_encrypt(dir, &iname, cryptbuf, len);
+ ret = fscrypt_fname_encrypt(dir,
+ &(struct qstr)QSTR_INIT(p, name_len),
+ cryptbuf, len);
if (ret) {
elen = ret;
goto out;
@@ -331,18 +330,13 @@ int ceph_encode_encrypted_dname(struct inode *parent, struct qstr *d_name,
}
/* base64 encode the encrypted name */
- elen = ceph_base64_encode(cryptbuf, len, buf);
- doutc(cl, "base64-encoded ciphertext name = %.*s\n", elen, buf);
+ elen = ceph_base64_encode(cryptbuf, len, p);
+ doutc(cl, "base64-encoded ciphertext name = %.*s\n", elen, p);
/* To understand the 240 limit, see CEPH_NOHASH_NAME_MAX comments */
WARN_ON(elen > 240);
- if ((elen > 0) && (dir != parent)) {
- char tmp_buf[NAME_MAX];
-
- elen = snprintf(tmp_buf, sizeof(tmp_buf), "_%.*s_%ld",
- elen, buf, dir->i_ino);
- memcpy(buf, tmp_buf, elen);
- }
+ if (dir != parent) // leading _ is already there; append _<inum>
+ elen += 1 + sprintf(p + elen, "_%ld", dir->i_ino);
out:
kfree(cryptbuf);
--
2.39.5
next prev parent reply other threads:[~2025-02-15 4:47 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 ` Al Viro [this message]
2025-02-15 12:41 ` [PATCH 1/2] prep for ceph_encode_encrypted_fname() fixes 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
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=20250215044714.GA3451131@ZenIV \
--to=viro@zeniv.linux.org.uk \
--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.