From 9eabf699946adec498ae42cbe5c1799d3bb0e4d8 Mon Sep 17 00:00:00 2001 From: dongyuzhen Date: Sat, 29 Jan 2022 19:07:09 +0800 Subject: [PATCH] Fix CVE-2021-43860 --- backport-0001-CVE-2021-43860.patch | 36 +++++ backport-0002-CVE-2021-43860.patch | 115 ++++++++++++++++ backport-0003-CVE-2021-43860.patch | 136 +++++++++++++++++++ backport-0004-CVE-2021-43860.patch | 210 +++++++++++++++++++++++++++++ flatpak.spec | 9 +- 5 files changed, 505 insertions(+), 1 deletion(-) create mode 100644 backport-0001-CVE-2021-43860.patch create mode 100644 backport-0002-CVE-2021-43860.patch create mode 100644 backport-0003-CVE-2021-43860.patch create mode 100644 backport-0004-CVE-2021-43860.patch diff --git a/backport-0001-CVE-2021-43860.patch b/backport-0001-CVE-2021-43860.patch new file mode 100644 index 0000000..dd6bfb4 --- /dev/null +++ b/backport-0001-CVE-2021-43860.patch @@ -0,0 +1,36 @@ +From 65cbfac982cb1c83993a9e19aa424daee8e9f042 Mon Sep 17 00:00:00 2001 +From: Alexander Larsson +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 56bca24..d6929ba 100644 +--- a/common/flatpak-dir.c ++++ b/common/flatpak-dir.c +@@ -7608,6 +7608,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; + + parts = flatpak_decompose_ref (ref, error); +-- +2.27.0 + diff --git a/backport-0002-CVE-2021-43860.patch b/backport-0002-CVE-2021-43860.patch new file mode 100644 index 0000000..4f1ec85 --- /dev/null +++ b/backport-0002-CVE-2021-43860.patch @@ -0,0 +1,115 @@ +From ba818f504c926baaf6e362be8159cfacf994310e Mon Sep 17 00:00:00 2001 +From: Ryan Gonzalez +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 + +Conflict:NA +Reference:https://github.com/flatpak/flatpak/commit/ba818f504c926baaf6e362be8159cfacf994310e + +--- + common/flatpak-dir.c | 5 +++-- + common/flatpak-transaction.c | 4 ++-- + common/flatpak-utils.c | 9 +++++---- + 3 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c +index 56bca24..5af4b4b 100644 +--- a/common/flatpak-dir.c ++++ b/common/flatpak-dir.c +@@ -6608,6 +6608,7 @@ flatpak_dir_deploy (FlatpakDir *self, + g_autoptr(GFile) metadata_file = NULL; + g_autofree char *metadata_contents = NULL; + g_autofree char *application_runtime = NULL; ++ gsize metadata_size = 0; + gboolean is_app; + + if (!flatpak_dir_ensure_repo (self, cancellable, error)) +@@ -6850,12 +6851,12 @@ flatpak_dir_deploy (FlatpakDir *self, + + 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)) + { + g_autoptr(GKeyFile) keyfile = g_key_file_new (); + if (!g_key_file_load_from_data (keyfile, + metadata_contents, +- -1, ++ metadata_size, + 0, error)) + return FALSE; + +diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c +index 396d75c..4e19e5d 100644 +--- a/common/flatpak-transaction.c ++++ b/common/flatpak-transaction.c +@@ -1604,7 +1604,7 @@ flatpak_transaction_add_ref (FlatpakTransaction *self, + + op = flatpak_transaction_add_op (self, remote, ref, subpaths, commit, bundle, kind); + 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; + } +@@ -1839,7 +1839,7 @@ load_deployed_metadata (FlatpakTransaction *self, const char *ref) + 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 +diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c +index 23b72d6..accf230 100644 +--- a/common/flatpak-utils.c ++++ b/common/flatpak-utils.c +@@ -4674,6 +4674,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; + +@@ -4691,6 +4692,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; +@@ -4760,12 +4763,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 + diff --git a/backport-0003-CVE-2021-43860.patch b/backport-0003-CVE-2021-43860.patch new file mode 100644 index 0000000..8a935f1 --- /dev/null +++ b/backport-0003-CVE-2021-43860.patch @@ -0,0 +1,136 @@ +From d9a8f9d8ccc0b7c1135d0ecde006a75d25f66aee Mon Sep 17 00:00:00 2001 +From: Alexander Larsson +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 | 36 +++++++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 15 deletions(-) + +diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c +index 4e19e5d..2134a3e 100644 +--- a/common/flatpak-transaction.c ++++ b/common/flatpak-transaction.c +@@ -1842,11 +1842,12 @@ load_deployed_metadata (FlatpakTransaction *self, const char *ref) + return g_bytes_new_take (g_steal_pointer (&metadata_contents), metadata_contents_length); + } + +-static void ++static gboolean + mark_op_resolved (FlatpakTransactionOperation *op, + const char *commit, + GBytes *metadata, +- GBytes *old_metadata) ++ GBytes *old_metadata, ++ GError **error) + { + g_debug ("marking op %s:%s resolved to %s", kind_to_str (op->kind), op->ref, commit ? commit : "-"); + +@@ -1860,13 +1861,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", 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, ++ _("Invalid .flatpakref: %s"), op->ref); ++ ++ op->resolved_metadata = g_bytes_ref (metadata); ++ op->resolved_metakey = g_steal_pointer (&metakey); + } + if (old_metadata) + { +@@ -1877,8 +1877,13 @@ 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", 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", op->ref); ++ } + } ++ ++ return TRUE; + } + + static gboolean +@@ -1922,7 +1927,7 @@ resolve_p2p_ops (FlatpakTransaction *self, + g_autoptr(GBytes) old_metadata_bytes = NULL; + + old_metadata_bytes = load_deployed_metadata (self, op->ref); +- mark_op_resolved (op, resolve->resolved_commit, resolve->resolved_metadata, old_metadata_bytes); ++ mark_op_resolved (op, resolve->resolved_commit, resolve->resolved_metadata, old_metadata_bytes,error); + } + + return TRUE; +@@ -1960,14 +1965,15 @@ resolve_ops (FlatpakTransaction *self, + /* We resolve to the deployed metadata, becasue we need it to uninstall related ops */ + + metadata_bytes = load_deployed_metadata (self, op->ref); +- mark_op_resolved (op, NULL, metadata_bytes, NULL); ++ mark_op_resolved (op, NULL, metadata_bytes, NULL,error); + continue; + } + + if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE) + { + g_assert (op->commit != NULL); +- mark_op_resolved (op, op->commit, op->external_metadata, NULL); ++ if (!mark_op_resolved (op, op->commit, NULL, NULL, error)) ++ return FALSE; + continue; + } + +@@ -1993,7 +1999,7 @@ resolve_ops (FlatpakTransaction *self, + metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata) + 1); + + old_metadata_bytes = load_deployed_metadata (self, op->ref); +- mark_op_resolved (op, checksum, metadata_bytes, old_metadata_bytes); ++ mark_op_resolved (op, checksum, metadata_bytes, old_metadata_bytes,error); + } + else if (state->collection_id == NULL) /* In the non-p2p case we have all the info available in the summary, so use it */ + { +@@ -2031,7 +2037,7 @@ resolve_ops (FlatpakTransaction *self, + metadata_bytes = g_bytes_new (metadata, strlen (metadata) + 1); + + old_metadata_bytes = load_deployed_metadata (self, op->ref); +- mark_op_resolved (op, checksum, metadata_bytes, old_metadata_bytes); ++ mark_op_resolved (op, checksum, metadata_bytes, old_metadata_bytes,error); + } + else + { +-- +2.27.0 + diff --git a/backport-0004-CVE-2021-43860.patch b/backport-0004-CVE-2021-43860.patch new file mode 100644 index 0000000..de528a8 --- /dev/null +++ b/backport-0004-CVE-2021-43860.patch @@ -0,0 +1,210 @@ +From 54ec1a482dfc668127eaae57f135e6a8e0bc52da Mon Sep 17 00:00:00 2001 +From: Phaedrus Leeds +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 fcbfcd9..afde01c 100644 +--- a/tests/Makefile-test-matrix.am.inc ++++ b/tests/Makefile-test-matrix.am.inc +@@ -17,6 +17,7 @@ TEST_MATRIX_DIST= \ + tests/test-basic.sh \ + tests/test-build-update-repo.sh \ + tests/test-http-utils.sh \ ++ tests/test-metadata-validation.sh \ + tests/test-extensions.sh \ + tests/test-oci.sh \ + tests/test-unsigned-summaries.sh \ +diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc +index d72de8a..b9a6f61 100644 +--- a/tests/Makefile.am.inc ++++ b/tests/Makefile.am.inc +@@ -93,6 +93,7 @@ TEST_MATRIX_SOURCE = \ + tests/test-http-utils.sh \ + tests/test-run.sh{{user+system},{nodeltas+deltas}} \ + tests/test-repo.sh{user+system+collections+collections-server-only} \ ++ tests/test-metadata-validation.sh \ + tests/test-extensions.sh \ + tests/test-bundle.sh{user+system} \ + 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 ++# ++# 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 <> ${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 + diff --git a/flatpak.spec b/flatpak.spec index 4c731af..ead9cf0 100644 --- a/flatpak.spec +++ b/flatpak.spec @@ -1,6 +1,6 @@ Name: flatpak Version: 1.0.3 -Release: 7 +Release: 8 Summary: Application deployment framework for desktop apps License: LGPLv2+ URL: http://flatpak.org/ @@ -26,6 +26,10 @@ Patch6006: backport-0007-CVE-2021-41133.patch Patch6007: backport-0008-CVE-2021-41133.patch Patch6008: backport-run-Handle-unknown-syscalls-as-intended.patch Patch6009: backport-Fix-handling-of-syscalls-only-allowed-by-devel.patch +Patch6010: backport-0001-CVE-2021-43860.patch +Patch6011: backport-0002-CVE-2021-43860.patch +Patch6012: backport-0003-CVE-2021-43860.patch +Patch6013: backport-0004-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) >= 2018.7 pkgconfig(polkit-gobject-1) pkgconfig(libseccomp) pkgconfig(xau) @@ -120,6 +124,9 @@ flatpak remote-list --system &> /dev/null || : %{_mandir}/man5/flatpak-remote.5* %changelog +* Sat Jan 29 2022 dongyuzhen - 1.0.3-8 +- Fix CVE-2021-43860 + * Wed Oct 20 2021 zhanzhimin - 1.0.3-7 - Fix CVE-2021-41133 -- Gitee