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 27 days ago.
Updated 25 days ago.
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'
- 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;
}
}
Also available in: Atom
PDF