dir: Validate GVariant structure before using generated variant readers

Reject summaries, subsummaries, and summary indexes that are not in
GVariant normal form before passing them to the generated variant
accessor framework, which performs direct pointer arithmetic without
structural validation.

Cherry-picked-from: 5a6c442c05
This commit is contained in:
Sebastian Wick committed 2026-08-27 20:53:24 +02:00
1 parent 353e1a5637
commit f006dd5bb3
1 file changed
+58 -8
+58 -8
View File
@@ -444,6 +444,44 @@ _validate_summary_for_collection_id (GVariant *summary_v,
return TRUE;
}
static GVariant *
summary_new_from_bytes_checked (GBytes *bytes,
GError **error)
{
g_autoptr(GVariant) v = NULL;
v = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
bytes, FALSE));
if (!g_variant_is_normal_form (v))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
_("Summary has invalid or corrupted data"));
return NULL;
}
return g_steal_pointer (&v);
}
static GVariant *
summary_index_new_from_bytes_checked (GBytes *bytes,
GError **error)
{
g_autoptr(GVariant) v = NULL;
v = g_variant_ref_sink (g_variant_new_from_bytes (FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT,
bytes, FALSE));
if (!g_variant_is_normal_form (v))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
_("Summary index has invalid or corrupted data"));
return NULL;
}
return g_steal_pointer (&v);
}
static void
flatpak_remote_state_add_sideload_repo (FlatpakRemoteState *self,
GFile *dir)
@@ -467,7 +505,14 @@ flatpak_remote_state_add_sideload_repo (FlatpakRemoteState *self,
FlatpakSideloadState *ss = g_new0 (FlatpakSideloadState, 1);
ss->repo = g_steal_pointer (&sideload_repo);
ss->summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, TRUE));
ss->summary = summary_new_from_bytes_checked (summary_bytes, NULL);
if (ss->summary == NULL)
{
g_info ("Sideload repo at path %s has invalid summary data",
flatpak_file_get_path_cached (dir));
flatpak_sideload_state_free (ss);
return;
}
if (!_validate_summary_for_collection_id (ss->summary, self->collection_id, &local_error))
{
@@ -598,7 +643,7 @@ flatpak_remote_state_ensure_subsummary (FlatpakRemoteState *self,
GCancellable *cancellable,
GError **error)
{
GVariant *subsummary;
g_autoptr(GVariant) subsummary = NULL;
const char *alt_arch;
GVariant *subsummary_info_v;
@@ -630,8 +675,11 @@ flatpak_remote_state_ensure_subsummary (FlatpakRemoteState *self,
&bytes, cancellable, error))
return FALSE;
subsummary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, FALSE));
g_hash_table_insert (self->subsummaries, g_strdup (arch), subsummary);
subsummary = summary_new_from_bytes_checked (bytes, error);
if (subsummary == NULL)
return FALSE;
g_hash_table_insert (self->subsummaries, g_strdup (arch), g_steal_pointer (&subsummary));
return TRUE;
}
@@ -14016,14 +14064,16 @@ _flatpak_dir_get_remote_state (FlatpakDir *self,
if (index_bytes)
{
state->index = g_variant_ref_sink (g_variant_new_from_bytes (FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT,
index_bytes, FALSE));
state->index = summary_index_new_from_bytes_checked (index_bytes, error);
if (state->index == NULL)
return NULL;
state->index_sig_bytes = g_steal_pointer (&index_sig_bytes);
}
else if (summary_bytes)
{
state->summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
summary_bytes, FALSE));
state->summary = summary_new_from_bytes_checked (summary_bytes, error);
if (state->summary == NULL)
return NULL;
state->summary_bytes = g_steal_pointer (&summary_bytes);
state->summary_sig_bytes = g_steal_pointer (&summary_sig_bytes);
}