From: Christopher Hoffman Date: Tue, 24 Jun 2025 17:47:17 +0000 (+0000) Subject: client: Rework fscrypt set policy to match fscrypt specification X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e46ac0a0b1d996a7b4865e725423ecd1213574bb;p=ceph.git client: Rework fscrypt set policy to match fscrypt specification When an fscrypt policy is set to an existing fscrypt directory it should only return EEXIST if policy being applied differs Signed-off-by: Christopher Hoffman --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 0c01b8702e5..da81477da47 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -18311,7 +18311,10 @@ int Client::set_fscrypt_policy_v2(int fd, const struct fscrypt_policy_v2& policy int Client::ll_set_fscrypt_policy_v2(Inode *in, const struct fscrypt_policy_v2& policy) { if (in->fscrypt_auth.size() > 0) { - return -EEXIST; + struct fscrypt_policy_v2 policy2; + in->fscrypt_ctx->convert_to(&policy2); + if (memcmp(&policy, &policy2, sizeof(policy))) + return -EEXIST; } if (!in->is_dir()) diff --git a/src/test/libcephfs/fscrypt.cc b/src/test/libcephfs/fscrypt.cc index 339953af1c3..d0b0156a67c 100644 --- a/src/test/libcephfs/fscrypt.cc +++ b/src/test/libcephfs/fscrypt.cc @@ -102,6 +102,7 @@ void populate_policy(struct ceph_fscrypt_key_identifier kid, struct fscrypt_poli policy->contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; policy->filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; policy->flags = FSCRYPT_POLICY_FLAGS_PAD_32; + memset(policy->__reserved, 0, sizeof(policy->__reserved)); memcpy(policy->master_key_identifier, kid.raw, FSCRYPT_KEY_IDENTIFIER_SIZE); } @@ -401,7 +402,7 @@ TEST(FSCrypt, SetPolicyNotEmptyDir) { ceph_shutdown(cmount); } -TEST(FSCrypt, SetPolicyAlreadyExistSameKey) { +TEST(FSCrypt, SetPolicyAlreadyExistSamePolicy) { struct ceph_fscrypt_key_identifier kid; struct ceph_mount_info* cmount; @@ -422,6 +423,43 @@ TEST(FSCrypt, SetPolicyAlreadyExistSameKey) { ASSERT_EQ(0, r); r = ceph_set_fscrypt_policy_v2(cmount, fd, &policy); + ASSERT_EQ(0, r); + + ceph_rmdir(cmount, dir_path.c_str()); + ceph_shutdown(cmount); +} + +TEST(FSCrypt, SetPolicyAlreadyExistDifferentPolicy) { + struct ceph_fscrypt_key_identifier kid; + + struct ceph_mount_info* cmount; + int r = init_mount(&cmount); + ASSERT_EQ(0, r); + + string dir_path = "dir2"; + ceph_mkdir(cmount, dir_path.c_str(), 0777); + + int fd = ceph_open(cmount, dir_path.c_str(), O_DIRECTORY, 0); + + r = ceph_add_fscrypt_key(cmount, fscrypt_key, sizeof(fscrypt_key), &kid, 1299); + + struct fscrypt_policy_v2 policy; + populate_policy(kid, &policy); + + r = ceph_set_fscrypt_policy_v2(cmount, fd, &policy); + ASSERT_EQ(0, r); + + char fscrypt_key2[32]; + for (int i = 0; i < (int)sizeof(fscrypt_key2); ++i) { + fscrypt_key2[i] = (char)rand(); + } + struct ceph_fscrypt_key_identifier kid2; + r = ceph_add_fscrypt_key(cmount, fscrypt_key2, sizeof(fscrypt_key2), &kid2, 1299); + + struct fscrypt_policy_v2 policy2; + populate_policy(kid2, &policy2); + + r = ceph_set_fscrypt_policy_v2(cmount, fd, &policy2); ASSERT_EQ(-EEXIST, r); ceph_rmdir(cmount, dir_path.c_str());