Project

General

Profile

Actions

Tasks #65615

closed

Tasks #63293: Implement fscrypt in libcephfs and cephfs-fuse

Tasks #64133: Make pjd work on fscrypt

lchown corrupts symlink entry

Added by Christopher Hoffman 14 days ago. Updated 12 days ago.

Status:
Resolved
Priority:
Normal
Category:
-
Target version:
-
% Done:

0%

Tags:
Reviewed:
Affected Versions:
Component(FS):
Labels (FS):
Pull request ID:

Description

lchown corrupts symlink entry:

# fstest create file1 0644
0
# fstest symlink file1 symlink1
0
# ls -l
total 1
-rw-r--r--. 1 root root  0 Apr 22 18:11 file1
lrwxrwxrwx. 1 root root 46 Apr 22 18:11 symlink1 -> file1
# fstest lchown symlink1 135 579
0
# ls -l
total 1
-rw-r--r--. 1 root root  0 Apr 22 18:11 file1
lrwxrwxrwx. 1  135  579 46 Apr 22 18:11 symlink1 -> ''$'\266\310''%'$'\005''W'$'\335''.'$'\355\211''kblD'$'\300''gq'$'\002\236\367''3'$'\255\201\001''Z6;'$'\221''&'$'\216\331\177''Q'
Actions #1

Updated by Christopher Hoffman 12 days ago

  • Status changed from In Progress to Resolved

The code was using parent dir ent fscrypt info/key. Using an incorrect key to decrypt, will yield incorrect plaintext.

Fix below:

commit 8b279179f26760eb4ac82079d52c256aad1f79b6 (HEAD -> wip-fscrypt)
Author: Christopher Hoffman <choffman@redhat.com>
Date:   Wed Apr 24 17:38:44 2024 +0000

    client: During lookup of fscrypt symlink, use target fscrypt info.

    During a lookup of fscrypt enabled symlink, use target fscrypt
    info. This must be used because enc key for each file is derived
    from master_key+nonce.

    Fixes: https://tracker.ceph.com/issues/65615
    Signed-off-by: Christopher Hoffman <choffman@redhat.com>

diff --git a/src/client/Client.cc b/src/client/Client.cc
index 6876573ba6e..72a01ec902f 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -7421,15 +7421,16 @@ int Client::_do_lookup(Inode *dir, const string& name, int mask,
   r = make_request(req, perms, target);
   ldout(cct, 10) << __func__ << " res is " << r << dendl;

-  if (r == 0 && (*target)->is_symlink()) {
-    auto fscrypt_denc = fscrypt->get_fname_denc(dir->fscrypt_ctx, &dir->fscrypt_key_validator, true);
+  auto inode = *target;
+  if (r == 0 && inode->is_symlink()) {
+    auto fscrypt_denc = fscrypt->get_fname_denc(inode->fscrypt_ctx, &inode->fscrypt_key_validator, true);
     if (fscrypt_denc) {
       string slname;
-      int ret = fscrypt_denc->get_decrypted_symlink((*target)->symlink, &slname);
+      int ret = fscrypt_denc->get_decrypted_symlink(inode->symlink, &slname);
       if (ret < 0) {
         ldout(cct, 0) << __FILE__ << ":" << __LINE__ << ": failed to decrypt symlink (r=" << ret << ")" << dendl;
       }
-      (*target)->symlink_plain = slname;
+      inode->symlink_plain = slname;
     }
   }

Actions

Also available in: Atom PDF