diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2025-02-14 23:37:58 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2025-06-17 17:58:14 -0400 |
| commit | 0d2da2561bdeb459b6c540c2417a15c1f8732e6a (patch) | |
| tree | ace92e44f378939e3cdcb75911e7de708a129d2e /fs/ceph/crypto.h | |
| parent | 28032ef879b6ab073bb8c85f2044edaf6b80c929 (diff) | |
| download | linux-next-0d2da2561bdeb459b6c540c2417a15c1f8732e6a.tar.gz linux-next-0d2da2561bdeb459b6c540c2417a15c1f8732e6a.zip | |
ceph: fix a race with rename() in ceph_mdsc_build_path()
Lift copying the name into callers of ceph_encode_encrypted_dname()
that do not have it already copied; ceph_encode_encrypted_fname()
disappears.
That fixes a UAF in ceph_mdsc_build_path() - while the initial copy
of plaintext into buf is done under ->d_lock, we access the
original name again in ceph_encode_encrypted_fname() and that is
done without any locking. With ceph_encode_encrypted_dname() using
the stable copy the problem goes away.
Tested-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ceph/crypto.h')
| -rw-r--r-- | fs/ceph/crypto.h | 18 |
1 files changed, 4 insertions, 14 deletions
diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h index d0768239a1c9..f752bbb2eb06 100644 --- a/fs/ceph/crypto.h +++ b/fs/ceph/crypto.h @@ -102,10 +102,7 @@ int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, struct ceph_acl_sec_ctx *as); void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, struct ceph_acl_sec_ctx *as); -int ceph_encode_encrypted_dname(struct inode *parent, struct qstr *d_name, - char *buf); -int ceph_encode_encrypted_fname(struct inode *parent, struct dentry *dentry, - char *buf); +int ceph_encode_encrypted_dname(struct inode *parent, char *buf, int len); static inline int ceph_fname_alloc_buffer(struct inode *parent, struct fscrypt_str *fname) @@ -194,17 +191,10 @@ static inline void ceph_fscrypt_as_ctx_to_req(struct ceph_mds_request *req, { } -static inline int ceph_encode_encrypted_dname(struct inode *parent, - struct qstr *d_name, char *buf) +static inline int ceph_encode_encrypted_dname(struct inode *parent, char *buf, + int len) { - memcpy(buf, d_name->name, d_name->len); - return d_name->len; -} - -static inline int ceph_encode_encrypted_fname(struct inode *parent, - struct dentry *dentry, char *buf) -{ - return -EOPNOTSUPP; + return len; } static inline int ceph_fname_alloc_buffer(struct inode *parent, |
