core: don't skip entries in _ostree_validate_structureof_xattrs
authorZibran Khan <kali834x@gmail.com>
Wed, 12 Aug 2026 21:33:43 +0000 (03:03 +0530)
committerZibran Khan <kali834x@gmail.com>
Wed, 12 Aug 2026 21:33:43 +0000 (03:03 +0530)
the for loop already advances the index, but the body incremented it a
second time, so only even-indexed xattrs were examined and the empty-name,
duplicate-name and sort-order checks skipped half the array. a crafted
dirmeta from a remote could hide an unsorted or duplicate xattr in an odd
slot and still pass ostree_validate_structureof_dirmeta.

src/libostree/ostree-core.c
tests/test-basic-c.c

index 12d11421aeb05d1cf58237361eee443f4caba6be..468b961d69735a964eefc0509dee8a8b3f1fe728 100644 (file)
@@ -2351,7 +2351,6 @@ _ostree_validate_structureof_xattrs (GVariant *xattrs, GError **error)
                                previous, name, i);
         }
       previous = name;
-      i++;
     }
   return TRUE;
 }
index 555c5802dac6495526552329826a33b141402cb6..81397f675cf1b7afdf38dd026a6c688ba946a143 100644 (file)
@@ -593,6 +593,19 @@ test_dirmeta_xattrs (void)
                                                 g_variant_builder_end (xattr_builder));
   g_assert (!ostree_validate_structureof_dirmeta (dirmeta, error));
   g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_FAILED);
+  g_clear_error (&local_error);
+
+  /* Every entry must be checked, including those at odd indices; a duplicate
+   * name in the second slot must still be rejected. */
+  g_autoptr (GVariantBuilder) dup_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ayay)"));
+  g_variant_builder_add (dup_builder, "(@ay@ay)", g_variant_new_bytestring ("user.a"),
+                         g_variant_new_bytestring (data));
+  g_variant_builder_add (dup_builder, "(@ay@ay)", g_variant_new_bytestring ("user.a"),
+                         g_variant_new_bytestring (data));
+  g_autoptr (GVariant) dup_dirmeta = g_variant_new ("(uuu@a(ayay))", uidgid, uidgid, mode,
+                                                    g_variant_builder_end (dup_builder));
+  g_assert (!ostree_validate_structureof_dirmeta (dup_dirmeta, error));
+  g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_FAILED);
 }
 
 int