From 8c3774e53c21fda9911c696eb751c7d653933005 Mon Sep 17 00:00:00 2001 From: Christopher Hoffman Date: Tue, 17 Feb 2026 18:51:51 +0000 Subject: [PATCH] client: During encryption of short case-insensitive file names, store raw ciphertext When writing alternate_name containing a short encrypted name, ensure that unarmored (not b64 encoded in this case) ciphertext is stored. Fixes: https://tracker.ceph.com/issues/74934 Signed-off-by: Christopher Hoffman --- src/client/Client.cc | 6 +++--- src/client/FSCrypt.cc | 8 ++++++-- src/client/FSCrypt.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 7e353b5c051..4e51b5ee31f 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -1414,7 +1414,7 @@ bool Client::_wrap_name(Inode& diri, std::string& dname, std::string& alternate_ if (fscrypt_denc) { string _enc_name; string _alt_name; - int r = fscrypt_denc->get_encrypted_fname(dname, &_enc_name, &_alt_name); + int r = fscrypt_denc->get_encrypted_fname(dname, &_enc_name, &_alt_name, false); if (r < 0) { ldout(cct, 0) << __FILE__ << ":" << __LINE__ << ": failed to encrypt filename" << dendl; return r; @@ -1425,12 +1425,12 @@ bool Client::_wrap_name(Inode& diri, std::string& dname, std::string& alternate_ alternate_name = std::move(_alt_name); } else { /* encrypt wrapped name */ - int r = fscrypt_denc->get_encrypted_fname(alternate_name, &_enc_name, &_alt_name); + int r = fscrypt_denc->get_encrypted_fname(alternate_name, &_enc_name, &_alt_name, true); if (r < 0) { ldout(cct, 0) << __FILE__ << ":" << __LINE__ << ": failed to encrypt filename" << dendl; return r; } - alternate_name = _alt_name.empty() ? std::move(_enc_name) : std::move(_alt_name); + alternate_name = std::move(_alt_name); } } #endif diff --git a/src/client/FSCrypt.cc b/src/client/FSCrypt.cc index 85cda61e566..57051c29e40 100644 --- a/src/client/FSCrypt.cc +++ b/src/client/FSCrypt.cc @@ -755,7 +755,7 @@ int FSCryptFNameDenc::get_encrypted_symlink_length(const int& plain_size) const return padded_size; } -int FSCryptFNameDenc::get_encrypted_fname(const std::string& plain, std::string *encrypted, std::string *alt_name) +int FSCryptFNameDenc::get_encrypted_fname(const std::string& plain, std::string *encrypted, std::string *alt_name, bool force_alt) { if (plain == "." || plain == ".." ) { *encrypted = plain; @@ -790,7 +790,11 @@ int FSCryptFNameDenc::get_encrypted_fname(const std::string& plain, std::string memcpy(extra, hash, sizeof(hash)); enc_len = CEPH_NOHASH_NAME_MAX + sizeof(hash); } else { - alt_name->clear(); + if (force_alt) { + *alt_name = std::string(enc_name, enc_len); + } else { + alt_name->clear(); + } } int b64_len = NAME_MAX * 2; // name.size() * 2; diff --git a/src/client/FSCrypt.h b/src/client/FSCrypt.h index b13ec4dbf4f..bf6222ecc76 100644 --- a/src/client/FSCrypt.h +++ b/src/client/FSCrypt.h @@ -293,7 +293,7 @@ public: bool setup_cipher() override; - int get_encrypted_fname(const std::string& plain, std::string *encrypted, std::string *alt_name); + int get_encrypted_fname(const std::string& plain, std::string *encrypted, std::string *alt_name, bool force_alt); int get_decrypted_fname(const std::string& b64enc, const std::string& alt_name, std::string *decrypted); int get_encrypted_symlink(const std::string& plain, std::string *encrypted); -- 2.47.3