]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: Use symlink_plain for decrypted fscrypt name
authorChristopher Hoffman <choffman@redhat.com>
Thu, 23 Jan 2025 20:22:10 +0000 (20:22 +0000)
committerChristopher Hoffman <choffman@redhat.com>
Wed, 5 Nov 2025 13:59:34 +0000 (13:59 +0000)
Use symlink_plain for only the value of a decrypted fscrypt
dname.

Signed-off-by: Christopher Hoffman <choffman@redhat.com>
src/client/Client.cc
src/client/Inode.h

index 73c93b8efdff398ef85a4612e46f3a7b67332e6d..6537ae9bf6003b5db7f4c405e9d62145375dbac1 100644 (file)
@@ -1837,8 +1837,6 @@ Inode* Client::insert_trace(MetaRequest *request, MetaSession *session)
           ldout(cct, 0) << __FILE__ << ":" << __LINE__ << ": failed to decrypt symlink (r=" << ret << ")" << dendl;
         }
         in->symlink_plain = slname;
-      } else {
-        in->symlink_plain = in->symlink;
       }
     }
   }
@@ -7690,8 +7688,6 @@ int Client::_do_lookup(const InodeRef& dir, const string& name, int mask,
         ldout(cct, 0) << __FILE__ << ":" << __LINE__ << ": failed to decrypt symlink (r=" << ret << ")" << dendl;
       }
       inode->symlink_plain = slname;
-    } else {
-      inode->symlink_plain = inode->symlink;
     }
   }
 
@@ -8285,14 +8281,25 @@ int Client::_readlink(const InodeRef& diri, const char* relpath, char *buf, size
     r = size;
 
   auto fscrypt_denc = fscrypt->get_fname_denc(in->fscrypt_ctx, &in->fscrypt_key_validator, true);
-  if (fscrypt_denc && in->symlink_plain.empty()) {
-    string dname;
-    int ret = fscrypt_denc->get_decrypted_symlink(in->symlink, &dname);
-    if (ret < 0) {
-      ldout(cct, 0) << __FILE__ << ":" << __LINE__ << ": failed to decrypt symlink (r=" << ret << ")" << dendl;
+
+  //There are three states a symlink could be in
+  // 1. Encrypted symlink not yet decrypted into memory
+  // 2. Encrypted symlink decrypted into memory
+  // 3. Regular symlink
+  if (fscrypt_denc) {
+    if (in->symlink_plain.empty()) {
+      string dname;
+      int ret = fscrypt_denc->get_decrypted_symlink(in->symlink, &dname);
+      if (ret < 0) {
+        ldout(cct, 0) << __FILE__ << ":" << __LINE__ << ": failed to decrypt symlink (r=" << ret << ")" << dendl;
+      }
+      memcpy(buf, dname.c_str(), dname.size());
+      r = dname.size();
+    } else {
+      // already buffered, copy plaintext to buf
+      memcpy(buf, in->symlink_plain.c_str(), in->symlink_plain.length());
+      r = in->symlink_plain.length();
     }
-    memcpy(buf, dname.c_str(), dname.size());
-    r = dname.size();
   } else {
     memcpy(buf, in->symlink.c_str(), r);
   }
index adae48030bbbe61be9417f71f6c199e5c19ad2fe..af2deed92263ae8794851d63571d2a0ad2401a51 100644 (file)
@@ -272,7 +272,7 @@ struct Inode : RefCountedObject {
   uint64_t  ll_ref = 0;   // separate ref count for ll client
   xlist<Dentry *> dentries; // if i'm linked to a dentry.
   std::string    symlink;  // symlink content, if it's a symlink
-  std::string    symlink_plain;  // decoded symlink (in-memory only)
+  std::string    symlink_plain;  // decrypted/decoded symlink (in-memory only)
   std::map<std::string,bufferptr> xattrs;
   std::map<frag_t,int> fragmap;  // known frag -> mds mappings
   std::map<frag_t, std::vector<mds_rank_t>> frag_repmap; // non-auth mds mappings