Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP2
flatpak.28335
CVE-2021-43860.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2021-43860.patch of Package flatpak.28335
diff -urpN flatpak-1.2.3.orig/common/flatpak-dir.c flatpak-1.2.3/common/flatpak-dir.c --- flatpak-1.2.3.orig/common/flatpak-dir.c 2022-08-31 15:19:04.784529834 -0500 +++ flatpak-1.2.3/common/flatpak-dir.c 2022-09-01 10:08:57.818529522 -0500 @@ -1003,19 +1003,28 @@ static gboolean validate_commit_metadata (GVariant *commit_data, const char *ref, const char *required_metadata, - gboolean require_xa_metadata, + gsize required_metadata_size, 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)) + 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); @@ -4806,8 +4815,12 @@ flatpak_dir_pull (FlatpakDir { 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), + error)) + goto out; } if (!flatpak_dir_pull_extra_data (self, repo, @@ -6949,9 +6962,9 @@ flatpak_dir_deploy (FlatpakDir g_auto(GLnxLockFile) lock = { 0, }; g_autoptr(GFile) metadata_file = NULL; g_autofree char *metadata_contents = NULL; + gsize metadata_size = 0; g_auto(GStrv) ref_parts = NULL; gboolean is_app; - gboolean is_oci; if (!flatpak_dir_ensure_repo (self, cancellable, error)) return FALSE; @@ -7194,11 +7207,12 @@ flatpak_dir_deploy (FlatpakDir 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; @@ -7209,11 +7223,8 @@ flatpak_dir_deploy (FlatpakDir /* 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, ref, metadata_contents, !is_oci, error)) + if (!validate_commit_metadata (commit_data, ref, metadata_contents, metadata_size, error)) return FALSE; dotref = g_file_resolve_relative_path (checkoutdir, "files/.ref"); @@ -7941,6 +7952,13 @@ flatpak_dir_ensure_bundle_remote (Flatpa 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); diff -urpN flatpak-1.2.3.orig/common/flatpak-transaction.c flatpak-1.2.3/common/flatpak-transaction.c --- flatpak-1.2.3.orig/common/flatpak-transaction.c 2022-08-31 15:19:04.784529834 -0500 +++ flatpak-1.2.3/common/flatpak-transaction.c 2022-09-01 10:10:36.199543664 -0500 @@ -1746,7 +1746,7 @@ flatpak_transaction_add_ref (FlatpakTran 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; } @@ -1988,14 +1988,15 @@ load_deployed_metadata (FlatpakTransacti 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 +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 : "-"); @@ -2009,13 +2010,12 @@ mark_op_resolved (FlatpakTransactionOper 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, + "Metadata for %s is invalid", op->ref); + + op->resolved_metadata = g_bytes_ref (metadata); + op->resolved_metakey = g_steal_pointer (&metakey); } if (old_metadata) { @@ -2026,8 +2026,13 @@ mark_op_resolved (FlatpakTransactionOper 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 @@ -2074,7 +2079,8 @@ resolve_p2p_ops (FlatpakTransaction *sel op->installed_size = resolve->installed_size; old_metadata_bytes = load_deployed_metadata (self, op->ref); - mark_op_resolved (op, resolve->resolved_commit, resolve->resolved_metadata, old_metadata_bytes); + if (!mark_op_resolved (op, resolve->resolved_commit, resolve->resolved_metadata, old_metadata_bytes, error)) + return FALSE; } return TRUE; @@ -2114,14 +2120,16 @@ 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); + if (!mark_op_resolved (op, 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, op->external_metadata, NULL); + if (!mark_op_resolved (op, op->commit, op->external_metadata, NULL, error)) + return FALSE; continue; } @@ -2157,7 +2165,7 @@ resolve_ops (FlatpakTransaction *self, if (xa_metadata == NULL) g_message ("Warning: No xa.metadata in local commit %s ref %s", checksum, 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); @@ -2165,7 +2173,8 @@ resolve_ops (FlatpakTransaction *self, op->installed_size = GUINT64_FROM_BE (installed_size); old_metadata_bytes = load_deployed_metadata (self, op->ref); - mark_op_resolved (op, checksum, metadata_bytes, old_metadata_bytes); + if (!mark_op_resolved (op, checksum, metadata_bytes, old_metadata_bytes, error)) + return FALSE; } else if (state->collection_id == NULL) /* In the non-p2p case we have all the info available in the summary, so use it */ { @@ -2200,13 +2209,14 @@ resolve_ops (FlatpakTransaction *self, g_clear_error (&local_error); } else - metadata_bytes = g_bytes_new (metadata, strlen (metadata) + 1); + metadata_bytes = g_bytes_new (metadata, strlen (metadata)); op->installed_size = installed_size; op->download_size = download_size; old_metadata_bytes = load_deployed_metadata (self, op->ref); - mark_op_resolved (op, checksum, metadata_bytes, old_metadata_bytes); + if (!mark_op_resolved (op, checksum, metadata_bytes, old_metadata_bytes, error)) + return FALSE; } else { diff -urpN flatpak-1.2.3.orig/common/flatpak-utils.c flatpak-1.2.3/common/flatpak-utils.c --- flatpak-1.2.3.orig/common/flatpak-utils.c 2022-08-30 16:26:04.237655063 -0500 +++ flatpak-1.2.3/common/flatpak-utils.c 2022-08-31 15:29:09.423721916 -0500 @@ -4799,6 +4799,7 @@ flatpak_pull_from_bundle (OstreeRepo * GCancellable *cancellable, GError **error) { + gsize metadata_size = 0; g_autofree char *metadata_contents = NULL; g_autofree char *to_checksum = NULL; @@ -4816,6 +4817,8 @@ flatpak_pull_from_bundle (OstreeRepo * 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; @@ -4885,12 +4888,10 @@ flatpak_pull_from_bundle (OstreeRepo * 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 { diff -urpN flatpak-1.2.3.orig/tests/Makefile.am.inc flatpak-1.2.3/tests/Makefile.am.inc --- flatpak-1.2.3.orig/tests/Makefile.am.inc 2019-02-11 07:44:28.000000000 -0600 +++ flatpak-1.2.3/tests/Makefile.am.inc 2022-09-01 09:47:56.657202015 -0500 @@ -127,6 +127,7 @@ TEST_MATRIX_SOURCE = \ tests/test-run.sh{{user+system},{nodeltas+deltas}} \ tests/test-info.sh{user+system} \ 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 -urpN flatpak-1.2.3.orig/tests/Makefile-test-matrix.am.inc flatpak-1.2.3/tests/Makefile-test-matrix.am.inc --- flatpak-1.2.3.orig/tests/Makefile-test-matrix.am.inc 2019-02-11 07:44:28.000000000 -0600 +++ flatpak-1.2.3/tests/Makefile-test-matrix.am.inc 2022-09-01 09:47:04.841037395 -0500 @@ -21,6 +21,7 @@ TEST_MATRIX_DIST= \ tests/test-config.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 -urpN flatpak-1.2.3.orig/tests/test-metadata-validation.sh flatpak-1.2.3/tests/test-metadata-validation.sh --- flatpak-1.2.3.orig/tests/test-metadata-validation.sh 1969-12-31 18:00:00.000000000 -0600 +++ flatpak-1.2.3/tests/test-metadata-validation.sh 2022-09-01 09:46:07.408854952 -0500 @@ -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"
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor