Actions
Tasks #65615
closedTasks #63293: Implement fscrypt in libcephfs and cephfs-fuse
Tasks #64133: Make pjd work on fscrypt
lchown corrupts symlink entry
% 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'
Updated by Christopher Hoffman 14 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