From 1d94f2679307bd3c73fac1afdd427d3f3be70a77 Mon Sep 17 00:00:00 2001 From: Christopher Hoffman Date: Mon, 18 Aug 2025 19:39:07 +0000 Subject: [PATCH] client: make FSCryptDecryptedInodes std::shared_ptr To help eliminate memory leaks, use std::shared_ptr for keeping track of FSCryptDecryptedInodes instances. Signed-off-by: Christopher Hoffman --- src/client/Client.cc | 35 +++++++++++++++++++++++++---------- src/client/FSCrypt.cc | 11 +++++++++-- src/client/FSCrypt.h | 5 ++++- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 8f9724c7157..57d6a0a51fa 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -10774,8 +10774,11 @@ int Client::_release_fh(Fh *f) if (in->snapid == CEPH_NOSNAP) { FSCryptKeyHandlerRef kh; get_keyhandler(in->fscrypt_ctx, kh); - if (kh && kh->di) { - kh->di->del_inode(in->ino); + if (kh) { + auto& di = kh->get_di(); + if (di) { + di->del_inode(in->ino); + } } if (in->put_open_ref(f->mode)) { _flush(in, new C_Client_FlushComplete(this, in)); @@ -10830,8 +10833,11 @@ int Client::_open(const InodeRef& in, int flags, mode_t mode, Fh **fhp, FSCryptKeyHandlerRef kh; get_keyhandler(in->fscrypt_ctx, kh); - if (kh && kh->di) { - kh->di->add_inode(in->ino); + if (kh) { + auto& di = kh->get_di(); + if (di) { + di->add_inode(in->ino); + } } in->get_open_ref(cmode); // make note of pending open, since it effects _wanted_ caps. @@ -10918,8 +10924,11 @@ int Client::_open(const InodeRef& in, int flags, mode_t mode, Fh **fhp, } else { FSCryptKeyHandlerRef kh; get_keyhandler(in->fscrypt_ctx, kh); - if (kh && kh->di) { - kh->di->del_inode(in->ino); + if (kh) { + auto& di = kh->get_di(); + if (di) { + di->del_inode(in->ino); + } } in->put_open_ref(cmode); } @@ -15755,8 +15764,11 @@ int Client::_create(const walk_dentry_result& wdr, int flags, mode_t mode, if(fhp) { FSCryptKeyHandlerRef kh; get_keyhandler((*inp)->fscrypt_ctx, kh); - if (kh && kh->di) { - kh->di->add_inode((*inp)->ino); + if (kh) { + auto& di = kh->get_di(); + if (di) { + di->add_inode((*inp)->ino); + } } (*inp)->get_open_ref(cmode); @@ -16184,9 +16196,12 @@ int Client::ll_rmdir(Inode *in, const char *name, const UserPerm& perms) int Client::get_keyhandler(FSCryptContextRef fscrypt_ctx, FSCryptKeyHandlerRef& kh){ if (fscrypt_ctx) { int r = fscrypt->get_key_store().find(fscrypt_ctx->master_key_identifier, kh); - if (kh) - if (kh && kh->di) + if (kh) { + auto& di = kh->get_di(); + if (di) { return r; + } + } } return 0; } diff --git a/src/client/FSCrypt.cc b/src/client/FSCrypt.cc index 466139a9512..60538079629 100644 --- a/src/client/FSCrypt.cc +++ b/src/client/FSCrypt.cc @@ -385,6 +385,12 @@ FSCryptKeyRef& FSCryptKeyHandler::get_key() return key; } +FSCryptDecryptedInodesRef& FSCryptKeyHandler::get_di() +{ + std::shared_lock rl{lock}; + return di; +} + //taken from fs/crypto/keyring.h bool FSCryptKeyStore::valid_key_spec(const struct fscrypt_key_specifier& k) { @@ -479,7 +485,9 @@ int FSCryptKeyStore::create(const char *k, int klen, FSCryptKeyHandlerRef& key_h return 0; //returns 0 regardless } key_handler->present = true; - key_handler->di = new FSCryptDecryptedInodes(); + + auto di = new FSCryptDecryptedInodes(); + key_handler->di = std::shared_ptr((FSCryptDecryptedInodes *)di); m[id] = key_handler; } @@ -533,7 +541,6 @@ int FSCryptKeyStore::invalidate(struct fscrypt_remove_key_arg* arg, int user) //do a final clean up if (!kh->present && kh->di->get_inodes().empty()) { kh->reset(++epoch, nullptr); - free(kh->di); m.erase(id); } else { r = 0; diff --git a/src/client/FSCrypt.h b/src/client/FSCrypt.h index 97d3f102952..9d58100ec65 100644 --- a/src/client/FSCrypt.h +++ b/src/client/FSCrypt.h @@ -324,6 +324,8 @@ public: } }; +using FSCryptDecryptedInodesRef = std::shared_ptr; + class FSCryptKeyHandler { ceph::shared_mutex lock = ceph::make_shared_mutex("FSCryptKeyHandler"); int64_t epoch = -1; @@ -336,9 +338,10 @@ public: void reset(int64_t epoch, FSCryptKeyRef k); int64_t get_epoch(); + FSCryptDecryptedInodesRef di; std::list& get_users() { return users; } FSCryptKeyRef& get_key(); - FSCryptDecryptedInodes* di; + FSCryptDecryptedInodesRef& get_di(); bool present = false; }; -- 2.39.5