Fix CVE-2021-43860

This commit is contained in:
dongyuzhen 2022-01-29 18:56:01 +08:00
parent ee03d27738
commit b078926f3a
6 changed files with 780 additions and 1 deletions

View File

@ -0,0 +1,210 @@
From 54ec1a482dfc668127eaae57f135e6a8e0bc52da Mon Sep 17 00:00:00 2001
From: Phaedrus Leeds <mwleeds@protonmail.com>
Date: Tue, 28 Dec 2021 11:48:16 -0800
Subject: [PATCH] Add test for metadata validation
This tests for invalid metadata, missing xa.metadata and mismatched
values in xa.metadata and the real metadata, including the embedded
null leading to the hidden permissions of CVE-2021-43860.
Conflict:NA
Reference:https://github.com/flatpak/flatpak/commit/54ec1a482dfc668127eaae57f135e6a8e0bc52da
---
tests/Makefile-test-matrix.am.inc | 1 +
tests/Makefile.am.inc | 1 +
tests/test-metadata-validation.sh | 158 ++++++++++++++++++++++++++++++
3 files changed, 160 insertions(+)
create mode 100644 tests/test-metadata-validation.sh
diff --git a/tests/Makefile-test-matrix.am.inc b/tests/Makefile-test-matrix.am.inc
index 30b402d..eef5a7e 100644
--- a/tests/Makefile-test-matrix.am.inc
+++ b/tests/Makefile-test-matrix.am.inc
@@ -36,6 +36,7 @@ TEST_MATRIX_DIST= \
tests/test-build-update-repo.sh \
tests/test-http-utils.sh \
tests/test-default-remotes.sh \
+ tests/test-metadata-validation.sh \
tests/test-extensions.sh \
tests/test-oci.sh \
tests/test-override.sh \
diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc
index 2458445..53d6403 100644
--- a/tests/Makefile.am.inc
+++ b/tests/Makefile.am.inc
@@ -216,6 +216,7 @@ TEST_MATRIX_SOURCE = \
tests/test-repo.sh{{user+system+system-norevokefs}+{{user+system},oldsummary}} \
tests/test-sideload.sh{user+system} \
tests/test-default-remotes.sh \
+ tests/test-metadata-validation.sh \
tests/test-extensions.sh \
tests/test-bundle.sh{user+system+system-norevokefs} \
tests/test-oci.sh \
diff --git a/tests/test-metadata-validation.sh b/tests/test-metadata-validation.sh
new file mode 100644
index 0000000..7e3efcc
--- /dev/null
+++ b/tests/test-metadata-validation.sh
@@ -0,0 +1,158 @@
+#!/bin/bash
+#
+# Copyright (C) 2021 Matthew Leeds <mwleeds@protonmail.com>
+#
+# SPDX-License-Identifier: LGPL-2.0-or-later
+
+set -euo pipefail
+
+. $(dirname $0)/libtest.sh
+
+echo "1..7"
+
+setup_repo
+
+COUNTER=1
+
+create_app () {
+ local OPTIONS="$1"
+ local DIR=`mktemp -d`
+
+ mkdir ${DIR}/files
+ echo $COUNTER > ${DIR}/files/counter
+ let COUNTER=COUNTER+1
+
+ local INVALID=""
+ if [[ $OPTIONS =~ "invalid" ]]; then
+ INVALID=invalidkeyfileline
+ fi
+ cat > ${DIR}/metadata <<EOF
+[Application]
+name=org.test.Malicious
+runtime=org.test.Platform/${ARCH}/master
+$INVALID
+
+[Context]
+EOF
+ if [[ $OPTIONS =~ "mismatch" ]]; then
+ echo -e "filesystems=host;" >> ${DIR}/metadata
+ fi
+ if [[ $OPTIONS =~ "hidden" ]]; then
+ echo -ne "\0" >> ${DIR}/metadata
+ echo -e "\nfilesystems=home;" >> ${DIR}/metadata
+ fi
+ local XA_METADATA=--add-metadata-string=xa.metadata="$(head -n6 ${DIR}/metadata)"$'\n'
+ if [[ $OPTIONS =~ "no-xametadata" ]]; then
+ XA_METADATA="--add-metadata-string=xa.nometadata=1"
+ fi
+ ostree commit --repo=repos/test --branch=app/org.test.Malicious/${ARCH}/master ${FL_GPGARGS} "$XA_METADATA" ${DIR}/
+ if [[ $OPTIONS =~ "no-cache-in-summary" ]]; then
+ ostree --repo=repos/test ${FL_GPGARGS} summary -u
+ # force use of legacy summary format
+ rm -rf repos/test/summary.idx repos/test/summaries
+ else
+ update_repo
+ fi
+ rm -rf ${DIR}
+}
+
+cleanup_repo () {
+ ostree refs --repo=repos/test --delete app/org.test.Malicious/${ARCH}/master
+ update_repo
+}
+
+create_app "hidden"
+
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
+ assert_not_reached "Should not be able to install app with hidden permissions"
+fi
+
+assert_file_has_content install-error-log "not matching expected metadata"
+
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
+
+cleanup_repo
+
+ok "app with hidden permissions can't be installed (CVE-2021-43860)"
+
+create_app no-xametadata
+
+# The install will fail because the metadata in the summary doesn't match the metadata on the commit
+# The missing xa.metadata in the commit got turned into "" in the xa.cache
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
+ assert_not_reached "Should not be able to install app with missing xa.metadata"
+fi
+
+assert_file_has_content install-error-log "not matching expected metadata"
+
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
+
+cleanup_repo
+
+ok "app with no xa.metadata can't be installed"
+
+create_app "no-xametadata no-cache-in-summary"
+
+# The install will fail because there's no metadata in the summary or on the commit
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
+ assert_not_reached "Should not be able to install app with missing metadata"
+fi
+assert_file_has_content install-error-log "No xa.metadata in local commit"
+
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
+
+cleanup_repo
+
+ok "app with no xa.metadata and no metadata in summary can't be installed"
+
+create_app "invalid"
+
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
+ assert_not_reached "Should not be able to install app with invalid metadata"
+fi
+assert_file_has_content install-error-log "Metadata for .* is invalid"
+
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
+
+cleanup_repo
+
+ok "app with invalid metadata (in summary) can't be installed"
+
+create_app "invalid no-cache-in-summary"
+
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
+ assert_not_reached "Should not be able to install app with invalid metadata"
+fi
+assert_file_has_content install-error-log "Metadata for .* is invalid"
+
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
+
+cleanup_repo
+
+ok "app with invalid metadata (in commit) can't be installed"
+
+create_app "mismatch no-cache-in-summary"
+
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
+ assert_not_reached "Should not be able to install app with non-matching metadata"
+fi
+assert_file_has_content install-error-log "Commit metadata for .* not matching expected metadata"
+
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
+
+cleanup_repo
+
+ok "app with mismatched metadata (in commit) can't be installed"
+
+create_app "mismatch"
+
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
+ assert_not_reached "Should not be able to install app with non-matching metadata"
+fi
+assert_file_has_content install-error-log "Commit metadata for .* not matching expected metadata"
+
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
+
+cleanup_repo
+
+ok "app with mismatched metadata (in summary) can't be installed"
--
2.27.0

View File

@ -0,0 +1,36 @@
From 65cbfac982cb1c83993a9e19aa424daee8e9f042 Mon Sep 17 00:00:00 2001
From: Alexander Larsson <alexl@redhat.com>
Date: Wed, 12 Jan 2022 11:00:56 +0100
Subject: [PATCH] Ensure that bundles have metadata on install
If we have a bundle without metadata we wouldn't properly present
the permissions in the transaction.
Conflict:NA
Reference:https://github.com/flatpak/flatpak/commit/65cbfac982cb1c83993a9e19aa424daee8e9f042
---
common/flatpak-dir.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
index 94a86f4..ddc5ee9 100644
--- a/common/flatpak-dir.c
+++ b/common/flatpak-dir.c
@@ -9295,6 +9295,13 @@ flatpak_dir_ensure_bundle_remote (FlatpakDir *self,
if (metadata == NULL)
return NULL;
+ /* If we rely on metadata (to e.g. print permissions), check it exists before creating the remote */
+ if (out_metadata && fp_metadata == NULL)
+ {
+ flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, "No metadata in bundler header");
+ return NULL;
+ }
+
gpg_data = extra_gpg_data ? extra_gpg_data : included_gpg_data;
deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, NULL);
--
2.27.0

View File

@ -0,0 +1,210 @@
From ba818f504c926baaf6e362be8159cfacf994310e Mon Sep 17 00:00:00 2001
From: Ryan Gonzalez <ryan.gonzalez@collabora.com>
Date: Thu, 23 Dec 2021 18:30:17 -0600
Subject: [PATCH] Fix metadata file contents after null terminators being
ignored
In particular, if a null terminator is placed inside the metadata file,
Flatpak will only compare the text *before* it to the value of
xa.metadata, but the full file will be parsed when permissions are set
at runtime. This means that any app can include a null terminator in its
permissions metadata, and Flatpak will only show the user the
permissions *preceding* the terminator during install, but the
permissions *after* the terminator are applied at runtime.
Fixes GHSA-qpjc-vq3c-572j / CVE-2021-43860
Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
Conflict:NA
Reference:https://github.com/flatpak/flatpak/commit/ba818f504c926baaf6e362be8159cfacf994310e
---
common/flatpak-dir.c | 36 +++++++++++++++++++++++++++---------
common/flatpak-transaction.c | 8 ++++----
common/flatpak-utils.c | 9 +++++----
3 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
index ddc5ee9..e6c8046 100644
--- a/common/flatpak-dir.c
+++ b/common/flatpak-dir.c
@@ -1762,19 +1762,29 @@ static gboolean
validate_commit_metadata (GVariant *commit_data,
const char *ref,
const char *required_metadata,
+ gsize required_metadata_size,
gboolean require_xa_metadata,
GError **error)
{
g_autoptr(GVariant) commit_metadata = NULL;
+ g_autoptr(GVariant) xa_metadata_v = NULL;
const char *xa_metadata = NULL;
+ gsize xa_metadata_size = 0;
commit_metadata = g_variant_get_child_value (commit_data, 0);
if (commit_metadata != NULL)
- g_variant_lookup (commit_metadata, "xa.metadata", "&s", &xa_metadata);
+ {
+ xa_metadata_v = g_variant_lookup_value (commit_metadata,
+ "xa.metadata",
+ G_VARIANT_TYPE_STRING);
+ if (xa_metadata_v)
+ xa_metadata = g_variant_get_string (xa_metadata_v, &xa_metadata_size);
+ }
if ((xa_metadata == NULL && require_xa_metadata) ||
- (xa_metadata != NULL && g_strcmp0 (required_metadata, xa_metadata) != 0))
+ (xa_metadata != NULL && (xa_metadata_size != required_metadata_size ||
+ memcmp (xa_metadata, required_metadata, xa_metadata_size) != 0)))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
_("Commit metadata for %s not matching expected metadata"), ref);
@@ -3478,6 +3488,7 @@ upgrade_deploy_data (GBytes *deploy_data,
g_autoptr(GKeyFile) keyfile = NULL;
g_autoptr(GFile) metadata_file = NULL;
g_autofree char *metadata_contents = NULL;
+ gsize metadata_size = 0;
g_autofree char *id = flatpak_decomposed_dup_id (ref);
/* Add fields from commit metadata to deploy */
@@ -3491,9 +3502,9 @@ upgrade_deploy_data (GBytes *deploy_data,
keyfile = g_key_file_new ();
metadata_file = g_file_resolve_relative_path (deploy_dir, "metadata");
if (!g_file_load_contents (metadata_file, cancellable,
- &metadata_contents, NULL, NULL, error))
+ &metadata_contents, &metadata_size, NULL, error))
return NULL;
- if (!g_key_file_load_from_data (keyfile, metadata_contents, -1, 0, error))
+ if (!g_key_file_load_from_data (keyfile, metadata_contents, metadata_size, 0, error))
return NULL;
add_metadata_to_deploy_data (&metadata_dict, keyfile);
@@ -5799,8 +5810,13 @@ flatpak_dir_pull (FlatpakDir *self,
{
g_autoptr(GVariant) commit_data = NULL;
if (!ostree_repo_load_commit (repo, rev, &commit_data, NULL, error) ||
- !validate_commit_metadata (commit_data, ref, (const char *)g_bytes_get_data (require_metadata, NULL), TRUE, error))
- return FALSE;
+ !validate_commit_metadata (commit_data,
+ ref,
+ (const char *)g_bytes_get_data (require_metadata, NULL),
+ g_bytes_get_size (require_metadata),
+ TRUE,
+ error))
+ goto out;
}
if (!flatpak_dir_pull_extra_data (self, repo,
@@ -8111,6 +8127,7 @@ flatpak_dir_deploy (FlatpakDir *self,
g_auto(GLnxLockFile) lock = { 0, };
g_autoptr(GFile) metadata_file = NULL;
g_autofree char *metadata_contents = NULL;
+ gsize metadata_size = 0;
gboolean is_oci;
if (!flatpak_dir_ensure_repo (self, cancellable, error))
@@ -8320,11 +8337,12 @@ flatpak_dir_deploy (FlatpakDir *self,
keyfile = g_key_file_new ();
metadata_file = g_file_resolve_relative_path (checkoutdir, "metadata");
if (g_file_load_contents (metadata_file, NULL,
- &metadata_contents, NULL, NULL, NULL))
+ &metadata_contents,
+ &metadata_size, NULL, NULL))
{
if (!g_key_file_load_from_data (keyfile,
metadata_contents,
- -1,
+ metadata_size,
0, error))
return FALSE;
@@ -8340,7 +8358,7 @@ flatpak_dir_deploy (FlatpakDir *self,
*/
is_oci = flatpak_dir_get_remote_oci (self, origin);
if (!validate_commit_metadata (commit_data, flatpak_decomposed_get_ref (ref),
- metadata_contents, !is_oci, error))
+ metadata_contents, metadata_size, !is_oci, error))
return FALSE;
dotref = g_file_resolve_relative_path (checkoutdir, "files/.ref");
diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c
index 1927498..721da14 100644
--- a/common/flatpak-transaction.c
+++ b/common/flatpak-transaction.c
@@ -2520,7 +2520,7 @@ flatpak_transaction_add_ref (FlatpakTransaction *self,
return FALSE;
if (external_metadata)
- op->external_metadata = g_bytes_new (external_metadata, strlen (external_metadata) + 1);
+ op->external_metadata = g_bytes_new (external_metadata, strlen (external_metadata));
return TRUE;
}
@@ -2937,7 +2937,7 @@ load_deployed_metadata (FlatpakTransaction *self, FlatpakDecomposed *ref, char *
return NULL;
}
- return g_bytes_new_take (g_steal_pointer (&metadata_contents), metadata_contents_length + 1);
+ return g_bytes_new_take (g_steal_pointer (&metadata_contents), metadata_contents_length);
}
static void
@@ -3034,7 +3034,7 @@ resolve_op_from_commit (FlatpakTransaction *self,
if (xa_metadata == NULL)
g_message ("Warning: No xa.metadata in local commit %s ref %s", checksum, flatpak_decomposed_get_ref (op->ref));
else
- metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata) + 1);
+ metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata));
if (g_variant_lookup (commit_metadata, "xa.download-size", "t", &download_size))
op->download_size = GUINT64_FROM_BE (download_size);
@@ -3074,7 +3074,7 @@ try_resolve_op_from_metadata (FlatpakTransaction *self,
&download_size, &installed_size, &metadata, NULL))
return FALSE;
- metadata_bytes = g_bytes_new (metadata, strlen (metadata) + 1);
+ metadata_bytes = g_bytes_new (metadata, strlen (metadata));
if (flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (op->ref),
NULL, NULL, &info, NULL, NULL))
diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c
index 6901a62..9eedbfa 100644
--- a/common/flatpak-utils.c
+++ b/common/flatpak-utils.c
@@ -6604,6 +6604,7 @@ flatpak_pull_from_bundle (OstreeRepo *repo,
GCancellable *cancellable,
GError **error)
{
+ gsize metadata_size = 0;
g_autofree char *metadata_contents = NULL;
g_autofree char *to_checksum = NULL;
g_autoptr(GFile) root = NULL;
@@ -6620,6 +6621,8 @@ flatpak_pull_from_bundle (OstreeRepo *repo,
if (metadata == NULL)
return FALSE;
+ metadata_size = strlen (metadata_contents);
+
if (!ostree_repo_get_remote_option (repo, remote, "collection-id", NULL,
&remote_collection_id, NULL))
remote_collection_id = NULL;
@@ -6689,12 +6692,10 @@ flatpak_pull_from_bundle (OstreeRepo *repo,
cancellable, error) < 0)
return FALSE;
- /* Null terminate */
- g_output_stream_write (G_OUTPUT_STREAM (data_stream), "\0", 1, NULL, NULL);
-
metadata_valid =
metadata_contents != NULL &&
- strcmp (metadata_contents, g_memory_output_stream_get_data (data_stream)) == 0;
+ metadata_size == g_memory_output_stream_get_data_size (data_stream) &&
+ memcmp (metadata_contents, g_memory_output_stream_get_data (data_stream), metadata_size) == 0;
}
else
{
--
2.27.0

View File

@ -0,0 +1,76 @@
From 93357d357119093804df05acc32ff335839c6451 Mon Sep 17 00:00:00 2001
From: Alexander Larsson <alexl@redhat.com>
Date: Tue, 11 Jan 2022 10:27:46 +0100
Subject: [PATCH] Require metadata in commit also for OCI remotes
This was disables a long time ago because the fedora remotes didn't
contain metadata, but that has been added since then. Requiring fixes
a security concern where an app claims to require no permissions (by
having no metadata in commit) but then actually requires permissions
in the installed app.
Conflict:NA
Reference:https://github.com/flatpak/flatpak/commit/93357d357119093804df05acc32ff335839c6451
---
common/flatpak-dir.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
index e6c8046..e6a83cf 100644
--- a/common/flatpak-dir.c
+++ b/common/flatpak-dir.c
@@ -1763,7 +1763,6 @@ validate_commit_metadata (GVariant *commit_data,
const char *ref,
const char *required_metadata,
gsize required_metadata_size,
- gboolean require_xa_metadata,
GError **error)
{
g_autoptr(GVariant) commit_metadata = NULL;
@@ -1782,9 +1781,9 @@ validate_commit_metadata (GVariant *commit_data,
xa_metadata = g_variant_get_string (xa_metadata_v, &xa_metadata_size);
}
- if ((xa_metadata == NULL && require_xa_metadata) ||
- (xa_metadata != NULL && (xa_metadata_size != required_metadata_size ||
- memcmp (xa_metadata, required_metadata, xa_metadata_size) != 0)))
+ if (xa_metadata == NULL ||
+ xa_metadata_size != required_metadata_size ||
+ memcmp (xa_metadata, required_metadata, xa_metadata_size) != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
_("Commit metadata for %s not matching expected metadata"), ref);
@@ -5814,7 +5813,6 @@ flatpak_dir_pull (FlatpakDir *self,
ref,
(const char *)g_bytes_get_data (require_metadata, NULL),
g_bytes_get_size (require_metadata),
- TRUE,
error))
goto out;
}
@@ -8128,7 +8126,6 @@ flatpak_dir_deploy (FlatpakDir *self,
g_autoptr(GFile) metadata_file = NULL;
g_autofree char *metadata_contents = NULL;
gsize metadata_size = 0;
- gboolean is_oci;
if (!flatpak_dir_ensure_repo (self, cancellable, error))
return FALSE;
@@ -8353,12 +8350,9 @@ flatpak_dir_deploy (FlatpakDir *self,
/* Check the metadata in the commit to make sure it matches the actual
* deployed metadata, in case we relied on the one in the commit for
* a decision
- * Note: For historical reason we don't enforce commits to contain xa.metadata
- * since this was lacking in fedora builds.
*/
- is_oci = flatpak_dir_get_remote_oci (self, origin);
if (!validate_commit_metadata (commit_data, flatpak_decomposed_get_ref (ref),
- metadata_contents, metadata_size, !is_oci, error))
+ metadata_contents, metadata_size, error))
return FALSE;
dotref = g_file_resolve_relative_path (checkoutdir, "files/.ref");
--
2.27.0

View File

@ -0,0 +1,239 @@
From d9a8f9d8ccc0b7c1135d0ecde006a75d25f66aee Mon Sep 17 00:00:00 2001
From: Alexander Larsson <alexl@redhat.com>
Date: Mon, 10 Jan 2022 16:43:08 +0100
Subject: [PATCH] Transaction: Fail the resolve if xa.metadata invalid or
missing
If we fail to parse xa.metadata from the summary cache or the commit
xa.metadata we fail the resolve.
If xa.metadata is missing in the commit we fail the resolve (it is
always set in the summary cache, because summary update converts
missing xa.metadata to "", so we either get that, or cache miss which
leads to resolving from the commit.
This means that op->resolved_metadata is always set during install and
updates, which means we will show the app permissions. The transaction
will also always make sure that this data actually matches what gets
deployed.
Before this change an invalid metadata in the summary cache could lead
to a NULL resolved_metadata, which means we wouldn't print the app
permissions, yet we would still deploy some metadata file that could
have permissions. (NOTE: It would fail to deploy unless the
xa.metadata in the commit matched the metadata file, but in this
corner case we would't compare the summary and commit metadata, so
they may differ.)
Conflict:NA
Reference:https://github.com/flatpak/flatpak/commit/d9a8f9d8ccc0b7c1135d0ecde006a75d25f66aee
---
common/flatpak-transaction.c | 84 +++++++++++++++++++++++-------------
1 file changed, 55 insertions(+), 29 deletions(-)
diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c
index 721da14..b0908c3 100644
--- a/common/flatpak-transaction.c
+++ b/common/flatpak-transaction.c
@@ -2957,12 +2957,13 @@ emit_eol_and_maybe_skip (FlatpakTransaction *self,
g_signal_emit (self, signals[END_OF_LIFED_WITH_REBASE], 0, op->remote, flatpak_decomposed_get_ref (op->ref), op->eol, op->eol_rebase, previous_ids, &op->skip);
}
-static void
+static gboolean
mark_op_resolved (FlatpakTransactionOperation *op,
const char *commit,
GFile *sideload_path,
GBytes *metadata,
- GBytes *old_metadata)
+ GBytes *old_metadata,
+ GError **error)
{
g_debug ("marking op %s:%s resolved to %s", kind_to_str (op->kind), flatpak_decomposed_get_ref (op->ref), commit ? commit : "-");
@@ -2980,13 +2981,12 @@ mark_op_resolved (FlatpakTransactionOperation *op,
if (metadata)
{
g_autoptr(GKeyFile) metakey = g_key_file_new ();
- if (g_key_file_load_from_bytes (metakey, metadata, G_KEY_FILE_NONE, NULL))
- {
- op->resolved_metadata = g_bytes_ref (metadata);
- op->resolved_metakey = g_steal_pointer (&metakey);
- }
- else
- g_message ("Warning: Failed to parse metadata for %s\n", flatpak_decomposed_get_ref (op->ref));
+ if (!g_key_file_load_from_bytes (metakey, metadata, G_KEY_FILE_NONE, NULL))
+ return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
+ "Metadata for %s is invalid", flatpak_decomposed_get_ref (op->ref));
+
+ op->resolved_metadata = g_bytes_ref (metadata);
+ op->resolved_metakey = g_steal_pointer (&metakey);
}
if (old_metadata)
{
@@ -2997,31 +2997,40 @@ mark_op_resolved (FlatpakTransactionOperation *op,
op->resolved_old_metakey = g_steal_pointer (&metakey);
}
else
- g_message ("Warning: Failed to parse old metadata for %s\n", flatpak_decomposed_get_ref (op->ref));
+ {
+ /* This shouldn't happen, but a NULL old metadata is safe (all permisssions are considered new) */
+ g_message ("Warning: Failed to parse old metadata for %s\n", flatpak_decomposed_get_ref (op->ref));
+ }
}
+
+ return TRUE;
}
-static void
+static gboolean
resolve_op_end (FlatpakTransaction *self,
FlatpakTransactionOperation *op,
const char *checksum,
GFile *sideload_path,
- GBytes *metadata_bytes)
+ GBytes *metadata_bytes,
+ GError **error)
{
g_autoptr(GBytes) old_metadata_bytes = NULL;
old_metadata_bytes = load_deployed_metadata (self, op->ref, NULL, NULL);
- mark_op_resolved (op, checksum, sideload_path, metadata_bytes, old_metadata_bytes);
+ if (!mark_op_resolved (op, checksum, sideload_path, metadata_bytes, old_metadata_bytes, error))
+ return FALSE;
emit_eol_and_maybe_skip (self, op);
+ return TRUE;
}
-static void
+static gboolean
resolve_op_from_commit (FlatpakTransaction *self,
FlatpakTransactionOperation *op,
const char *checksum,
GFile *sideload_path,
- GVariant *commit_data)
+ GVariant *commit_data,
+ GError **error)
{
g_autoptr(GBytes) metadata_bytes = NULL;
g_autoptr(GVariant) commit_metadata = NULL;
@@ -3032,9 +3041,11 @@ resolve_op_from_commit (FlatpakTransaction *self,
commit_metadata = g_variant_get_child_value (commit_data, 0);
g_variant_lookup (commit_metadata, "xa.metadata", "&s", &xa_metadata);
if (xa_metadata == NULL)
- g_message ("Warning: No xa.metadata in local commit %s ref %s", checksum, flatpak_decomposed_get_ref (op->ref));
- else
- metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata));
+ return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
+ "No xa.metadata in local commit %s ref %s",
+ checksum, flatpak_decomposed_get_ref (op->ref));
+
+ metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata));
if (g_variant_lookup (commit_metadata, "xa.download-size", "t", &download_size))
op->download_size = GUINT64_FROM_BE (download_size);
@@ -3044,15 +3055,19 @@ resolve_op_from_commit (FlatpakTransaction *self,
g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE, "s", &op->eol);
g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, "s", &op->eol_rebase);
- resolve_op_end (self, op, checksum, sideload_path, metadata_bytes);
+ return resolve_op_end (self, op, checksum, sideload_path, metadata_bytes, error);
}
+/* NOTE: In case of non-available summary this returns FALSE with a
+ * NULL error, but for other error cases it will be set.
+ */
static gboolean
try_resolve_op_from_metadata (FlatpakTransaction *self,
FlatpakTransactionOperation *op,
const char *checksum,
GFile *sideload_path,
- FlatpakRemoteState *state)
+ FlatpakRemoteState *state,
+ GError **error)
{
g_autoptr(GBytes) metadata_bytes = NULL;
guint64 download_size = 0;
@@ -3092,8 +3107,7 @@ try_resolve_op_from_metadata (FlatpakTransaction *self,
op->token_type = GINT32_FROM_LE (var_metadata_lookup_int32 (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_TOKEN_TYPE, op->token_type));
}
- resolve_op_end (self, op, checksum, sideload_path, metadata_bytes);
- return TRUE;
+ return resolve_op_end (self, op, checksum, sideload_path, metadata_bytes, error);
}
static gboolean
@@ -3136,7 +3150,8 @@ resolve_ops (FlatpakTransaction *self,
* checksum we got was the version already installed.
*/
g_assert (op->resolved_commit != NULL);
- mark_op_resolved (op, op->resolved_commit, NULL, NULL, NULL);
+ if (!mark_op_resolved (op, op->resolved_commit, NULL, NULL, NULL, error))
+ return FALSE;
continue;
}
@@ -3145,14 +3160,16 @@ resolve_ops (FlatpakTransaction *self,
/* We resolve to the deployed metadata, because we need it to uninstall related ops */
metadata_bytes = load_deployed_metadata (self, op->ref, &checksum, NULL);
- mark_op_resolved (op, checksum, NULL, metadata_bytes, NULL);
+ if (!mark_op_resolved (op, checksum, NULL, metadata_bytes, NULL, error))
+ return FALSE;
continue;
}
if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE)
{
g_assert (op->commit != NULL);
- mark_op_resolved (op, op->commit, NULL, op->external_metadata, NULL);
+ if (!mark_op_resolved (op, op->commit, NULL, op->external_metadata, NULL, error))
+ return FALSE;
continue;
}
@@ -3183,7 +3200,8 @@ resolve_ops (FlatpakTransaction *self,
if (commit_data == NULL)
return FALSE;
- resolve_op_from_commit (self, op, checksum, NULL, commit_data);
+ if (!resolve_op_from_commit (self, op, checksum, NULL, commit_data, error))
+ return FALSE;
}
else
{
@@ -3242,9 +3260,16 @@ resolve_ops (FlatpakTransaction *self,
}
/* First try to resolve via metadata (if remote is available and its metadata matches the commit version) */
- if (!try_resolve_op_from_metadata (self, op, checksum, sideload_path, state))
+ if (!try_resolve_op_from_metadata (self, op, checksum, sideload_path, state, &local_error))
{
- /* Else try to load the commit object.
+ if (local_error)
+ {
+ /* Actual error, not just missing from summary */
+ g_propagate_error (error, g_steal_pointer (&local_error));
+ return FALSE;
+ }
+
+ /* Missing from summary, try to load the commit object.
* Note, we don't have a token here, so this will not work for authenticated apps.
* We handle this by catching the 401 http status and retrying. */
g_autoptr(GVariant) commit_data = NULL;
@@ -3280,7 +3305,8 @@ resolve_ops (FlatpakTransaction *self,
return FALSE;
}
- resolve_op_from_commit (self, op, checksum, sideload_path, commit_data);
+ if (!resolve_op_from_commit (self, op, checksum, sideload_path, commit_data, error))
+ return FALSE;
}
}
}
--
2.27.0

View File

@ -1,6 +1,6 @@
Name: flatpak
Version: 1.10.2
Release: 4
Release: 5
Summary: Application deployment framework for desktop apps
License: LGPLv2+
URL: http://flatpak.org/
@ -21,6 +21,11 @@ Patch6008: backport-run-Handle-unknown-syscalls-as-intended.patch
Patch6009: backport-Fix-handling-of-syscalls-only-allowed-by-de.patch
Patch6010: backport-support-new-pyparsing.patch
Patch6011: backport-CVE-2022-21682.patch
Patch6012: backport-0001-CVE-2021-43860.patch
Patch6013: backport-0002-CVE-2021-43860.patch
Patch6014: backport-0003-CVE-2021-43860.patch
Patch6015: backport-0004-CVE-2021-43860.patch
Patch6016: backport-0005-CVE-2021-43860.patch
BuildRequires: pkgconfig(appstream-glib) pkgconfig(gio-unix-2.0) pkgconfig(gobject-introspection-1.0) >= 1.40.0 pkgconfig(json-glib-1.0) pkgconfig(libarchive) >= 2.8.0
BuildRequires: pkgconfig(libsoup-2.4) pkgconfig(libxml-2.0) >= 2.4 pkgconfig(ostree-1) >= 2020.8 pkgconfig(polkit-gobject-1) pkgconfig(libseccomp) pkgconfig(xau)
@ -126,6 +131,9 @@ flatpak remote-list --system &> /dev/null || :
%{_mandir}/man5/flatpak-remote.5*
%changelog
* Sat Jan 29 2022 dongyuzhen <dongyuzhen@h-partners.com> - 1.10.2-5
- Fix CVE-2021-43860
* Tue Jan 25 2022 hanhui <hanhui15@huawei.com> - 1.10.2-4
- Fix CVE-2022-21682