Tasks #64137
closedTasks #63293: Implement fscrypt in libcephfs and cephfs-fuse
Implement way to see locked status
0%
Description
Currently, there's a notion of "fscrypt_ctx" within Inode on Client. When this is non-nullptr, that means the inode should be unlocked.
On a new filesystem, without fscrypt unlocked, fscrypt_ctx is non-nullptr. Need to track down why this gets set.
From a comment:
// userland clients are only allowed to read if fscrypt enabled but no fscrypt ctx exists
// (is locked)
Steps to reproduce:
1. encrypt dir w/fscrypt
2. umount/remount file system
3. list encrypted dir contents
At this point, in->fscrypt_ctx will not be nullptr and comment above is false.
Updated by Patrick Donnelly about 2 years ago
- Assignee set to Christopher Hoffman
Updated by Christopher Hoffman over 1 year ago
- Status changed from New to In Progress
Updated by Igor Golikov over 1 year ago
- Assignee changed from Christopher Hoffman to Igor Golikov
Updated by Igor Golikov over 1 year ago
- Assignee changed from Igor Golikov to Christopher Hoffman
Updated by Christopher Hoffman about 1 year ago ยท Edited
- Status changed from In Progress to Resolved
fscrypt_ctx is a representation of fscrypt_auth. Whenever fscrypt_auth gets set or updated, fscrypt_ctx gets created. The preferred way to see locked status is to use is_inode_locked()
Did an audit of fscrypt_ctx usage and fixed cases where needed. See below. Changed the boolean to is_inode_locked, as fscrypt_ctx will always be set when fscrypt is enabled. Also added in a return statement that got removed.
Author: Christopher Hoffman <choffman@redhat.com>
Date: Wed Jan 8 15:32:23 2025 +0000
client: change conditional to check for is locked.
Fixes: https://tracker.ceph.com/issues/64137
Signed-off-by: Christopher Hoffman <choffman@redhat.com>
diff --git a/src/client/Client.cc b/src/client/Client.cc
index 9560593311f..4288de9e7f2 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -3832,10 +3832,9 @@ int Client::get_caps(Fh *fh, int need, int want, int *phave, loff_t endoff)
if ((need & CEPH_CAP_FILE_WR) &&
((in->auth_cap && in->auth_cap->session->readonly) ||
- // userland clients are only allowed to read if fscrypt enabled but no fscrypt ctx exists
- // (is locked)
- (in->is_fscrypt_enabled() && !in->fscrypt_ctx)))
-
+ // userland clients are only allowed to read if fscrypt enabled and is locked
+ (in->is_fscrypt_enabled() && is_inode_locked(in))))
+ return -CEPHFS_EROFS;
if (in->flags & I_CAP_DROPPED) {
int mds_wanted = in->caps_mds_wanted();
if ((mds_wanted & need) != need) {
diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc
index 0dfaa4568c9..1940f5572e2 100644
--- a/src/client/fuse_ll.cc
+++ b/src/client/fuse_ll.cc
@@ -969,7 +969,7 @@ static void fuse_ll_ioctl(fuse_req_t req, fuse_ino_t ino,
Fh *fh = (Fh*)fi->fh;
Inode *in = fh->inode.get();
- if (in->fscrypt_ctx) {
+ if (in->is_fscrypt_enabled()) {
in->fscrypt_ctx->convert_to(&out_arg.policy.v2);
out_arg.policy_size = sizeof(out_arg.policy);