From: Christopher Hoffman Date: Fri, 14 Nov 2025 19:18:13 +0000 (+0000) Subject: client: Only used known fields when comparing policies X-Git-Tag: testing/wip-vshankar-testing-20260219.125903~6^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=70c4c79d9794bba62f32aa77bafe392de6022dc3;p=ceph-ci.git client: Only used known fields when comparing policies In set fscrypt policy, only use known fields when comparing if an existing policy matches provided policy. This is needed as struct fscrypt_policy_v2 has a reserved field. Since this is a value managed in the kernel, it can change without notice. A field was recently added: log2_data_unit_size. This can cause issues with comparing existing policies during set policy. When fields are added, reserved size changes and we can run into trying to compare the same policies that compare uninitialized memory regions or regions we do not yet support. Fixes: https://tracker.ceph.com/issues/73825 Signed-off-by: Christopher Hoffman --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 7157f7a3c4d..8cdc1919472 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -18530,7 +18530,10 @@ int Client::ll_set_fscrypt_policy_v2(Inode *in, const struct fscrypt_policy_v2& if (in->is_fscrypt_enabled()) { struct fscrypt_policy_v2 policy2; in->fscrypt_ctx->convert_to(&policy2); - if (memcmp(&policy, &policy2, sizeof(policy))) { + + struct fscrypt_policy_v2 policy_standardized; + in->fscrypt_ctx->standardize(policy, &policy_standardized); + if (memcmp(&policy_standardized, &policy2, sizeof(policy))) { return -EEXIST; } return 0; diff --git a/src/client/FSCrypt.h b/src/client/FSCrypt.h index b13ec4dbf4f..c9b318e7065 100644 --- a/src/client/FSCrypt.h +++ b/src/client/FSCrypt.h @@ -199,12 +199,23 @@ public: virtual void encode_extra(bufferlist& bl) const {} + void standardize(struct fscrypt_policy_v2 src, struct fscrypt_policy_v2 *dest) { + memset(dest, 0, sizeof(struct fscrypt_policy_v2)); + + dest->version = src.version; + dest->contents_encryption_mode = src.contents_encryption_mode; + dest->filenames_encryption_mode = src.filenames_encryption_mode; + dest->flags = src.flags; + memcpy(dest->master_key_identifier, src.master_key_identifier, sizeof(src.master_key_identifier)); + } + void convert_to(struct fscrypt_policy_v2 *dest) { + memset(dest, 0, sizeof(struct fscrypt_policy_v2)); + dest->version = version; dest->contents_encryption_mode = contents_encryption_mode; dest->filenames_encryption_mode = filenames_encryption_mode; dest->flags = flags; - memset(dest->__reserved, 0, sizeof(dest->__reserved)); memcpy(dest->master_key_identifier, master_key_identifier.raw, sizeof(master_key_identifier.raw)); }