]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
client: Only used known fields when comparing policies
authorChristopher Hoffman <choffman@redhat.com>
Fri, 14 Nov 2025 19:18:13 +0000 (19:18 +0000)
committerChristopher Hoffman <choffman@redhat.com>
Mon, 17 Nov 2025 16:35:35 +0000 (16:35 +0000)
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 <choffman@redhat.com>
src/client/Client.cc
src/client/FSCrypt.h

index 7157f7a3c4dd0902b0cb4b60403cac0a05e3bbb0..8cdc1919472ad566446c71bf9643d2288e94d37b 100644 (file)
@@ -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;
index b13ec4dbf4f0a2f597330502860b258fc412855f..c9b318e70659d537de8e9e1d791013da9462100c 100644 (file)
@@ -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));
   }