Fix CVE-2021-43860
This commit is contained in:
parent
ee03d27738
commit
b078926f3a
210
backport-0001-CVE-2021-43860.patch
Normal file
210
backport-0001-CVE-2021-43860.patch
Normal 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
|
||||
|
||||
36
backport-0002-CVE-2021-43860.patch
Normal file
36
backport-0002-CVE-2021-43860.patch
Normal 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
|
||||
|
||||
210
backport-0003-CVE-2021-43860.patch
Normal file
210
backport-0003-CVE-2021-43860.patch
Normal 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
|
||||
|
||||
76
backport-0004-CVE-2021-43860.patch
Normal file
76
backport-0004-CVE-2021-43860.patch
Normal 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
|
||||
|
||||
239
backport-0005-CVE-2021-43860.patch
Normal file
239
backport-0005-CVE-2021-43860.patch
Normal 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
|
||||
|
||||
10
flatpak.spec
10
flatpak.spec
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user